我目前正在創建一個包含兩部分的注冊頁面
- 一部分是關于用戶名和密碼。
- 第二部分是關于選擇自己的PC-Configuration
定義完所有內容后,用戶可以注冊以進入主頁。
因此,我得到了一個名為“PC_Configuration”的模型,其中包含一組指向處理器/圖形卡等不同資料庫模型的外鍵:
class PC_Configuration(models.Model):
user = models.ForeignKey(User, related_name='user_id', on_delete=models.DO_NOTHING)
processor = models.ForeignKey(Processors, related_name='processor_id', on_delete=models.DO_NOTHING)
graphicscard = models.ForeignKey(Graphicscard, related_name='graphicscard_id', on_delete=models.DO_NOTHING)
os = models.ForeignKey(OS, related_name='os_id', on_delete=models.DO_NOTHING)
ram = models.ForeignKey(RAM, related_name='ram_id', on_delete=models.DO_NOTHING)
harddrive = models.ForeignKey(Harddrive, related_name='harddrive_id', on_delete=models.DO_NOTHING)
此外,用戶有一個外鍵,用于將配置連接到相應的用戶 ID。
在views.py 中,我一直在為用戶自己選擇的所有下拉欄位創建一個 DropdownForm :
class DropdownForm(forms.ModelForm):
class Meta:
model = models.PC_Configuration
exclude = []
def __init__(self, *args, **kwargs):
super(DropdownForm, self).__init__(*args, **kwargs)
self.fields['processors'].queryset = DropdownForm.objects.all()
self.fields['processors'].label_from_instance = lambda obj: "%s" % obj.name
self.fields['graphicscard'].queryset = DropdownForm.objects.all()
self.fields['graphicscard'].label_from_instance = lambda obj: "%s" % obj.name
self.fields['os'].queryset = DropdownForm.objects.all()
self.fields['os'].label_from_instance = lambda obj: "%s" % obj.name
self.fields['ram'].queryset = DropdownForm.objects.all()
self.fields['ram'].label_from_instance = lambda obj: "%s" % obj.name
self.fields['harddrive'].queryset = DropdownForm.objects.all()
self.fields['harddrive'].label_from_instance = lambda obj: "%s" % obj.name
但考慮到用戶 ID 應自動分配給配置的事實,這里沒有欄位。
它在 register_view(request) - 方法中定義:
def register_view(request):
form = DropdownForm()
if request.method == "POST":
form = DropdownForm(request.POST)
username = request.POST.get('username')
password = request.POST.get('password')
myuser = User.objects.create_user(username, None, password)
myuser.save()
auth.login(request, myuser)
#form.user = request.user
print(form.errors)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
messages.success(request, "Account has been created successfully")
return redirect(reverse('gamesearch_view'))
else:
print('Failed')
form = DropdownForm()
render(request, 'register.html', dict(form=form))
return render(request, 'register.html', dict(form=form))
在這里,我們遇到了問題,我猜。在測驗注冊時,Testaccounts 不斷創建并成功登錄。但問題是,由于表單未驗證,因此沒有創建 PC 配置。
和
print(form.errors)
我一直在試圖弄清楚為什么會這樣,它說
<ul class="errorlist"><li>user<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
因此,似乎有必要在檢查之前定義“用戶”欄位,如果表單正在驗證并隨后在實體中定義用戶。
這就是為什么我試圖這樣做:
form.user = request.user
但它仍然無法正常作業,我無法弄清楚究竟是什么問題,因為“用戶”不應該成為表單驗證的一部分。
你能幫我一下嗎?
先感謝您!
uj5u.com熱心網友回復:
有了這樣的事情,你會有一個更簡單的時間......
- 你
related_name的有點假;從另一個模型的“觀點”來看,它們應該是相反的名稱。(此外,您永遠不需要_id在 Django 中手動添加欄位。)如果您省略 related_names,它們將隱式為pc_configuration_set. on_delete=DO_NOTHING可能不是一個好主意。PROTECT是一個很好的默認值。- 將用戶名和密碼作為表單中的欄位處理會更容易。
- 您丟失了
exclude = ["user"],因此如果您的模板沒有為 呈現欄位user,那么它當然會丟失。但是,您也不希望表單的 POSTer 提交任何舊的用戶 ID。 - 使用 a
FormView洗掉了管理表單所需的大部分樣板。 transaction.atomic()如果保存 PC 配置失敗,我們正在使用以確保用戶不會最終保存到資料庫中。- 我們將創建的用戶分配給
form.instance,這是新的但尚未保存的 PC 配置。
(當然,想象一下這些在單獨的檔案中。)
from django import forms
from django.db import models, transaction
from django.views.generic import FormView
class PC_Configuration(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
processor = models.ForeignKey(Processors, on_delete=models.PROTECT)
graphicscard = models.ForeignKey(Graphicscard, on_delete=models.PROTECT)
os = models.ForeignKey(OS, on_delete=models.PROTECT)
ram = models.ForeignKey(RAM, on_delete=models.PROTECT)
harddrive = models.ForeignKey(Harddrive, on_delete=models.PROTECT)
class RegisterAndConfigurePCForm(forms.ModelForm):
username = forms.CharField(required=True)
password = forms.CharField(required=True, widget=forms.PasswordInput())
class Meta:
model = PC_Configuration
exclude = ["user"] # we'll assign this by hand
class RegisterAndConfigureView(FormView):
form_class = RegisterAndConfigurePCForm
template_name = "register.html"
def form_valid(self, form):
with transaction.atomic():
user = User.objects.create_user(form.cleaned_data["username"], None, form.cleaned_data["password"])
form.instance.user = user # assign user to the to-be-created PC configuration
form.save()
return redirect(reverse("gamesearch_view"))
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/371684.html
