以下解决方案对我有用。我使用表单集来创建这个解决方案。
我的模型如下,
型号:
#Custom user model
class CustomUserManager(BaseUserManager):
def create_user(self, email, password, **extra_fields):
if not email:
raise ValueError(_('The Email must be set'))
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
class CustomUser(AbstractUser):
username = None
email = models.EmailField(_('email address'), unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
#Related model(One-to-One relationship with custom user)
class Student(models.Model):
user = models.OneToOneField(CustomUser,on_delete = models.CASCADE)
first_name = models.CharField(max_length=50)
middle_name = models.CharField(max_length=50,blank=True,null=True)
last_name = models.CharField(max_length=50,blank=True,null=True)
之后我创建了两个 ModelForms
表格
from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser,Student
from django import forms
# Form for custom user
class SignUpForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ('email', 'password1', 'password2')
class StudentCreationForm(forms.ModelForm):
class Meta:
model = Student
fields = ['user','first_name','middle_name','last_name']
现在是主要部分,我创建了一个简单的内联 formset 工厂来处理 Student 模型作为内联表单。
表单集
from django.forms import inlineformset_factory
from .models import CustomUser,Student
from .forms import StudentCreationForm
# As parameters I provided parent Model(CustomUser),child Model(Student) and the Child
# ModelForm(StudentCreationForm)
StudentCreationFormSet = inlineformset_factory(CustomUser, Student,form=StudentCreationForm,extra=1,can_delete = False)
在视图中,我分别创建了 SignUpForm 和 StudentCreationFormSet 对象。在 POST 请求中,我首先验证了 CustomUser 表单并保存它而不提交它(commit=False)。我创建了一个自定义用户对象并将其作为实例传递给 StudentCreationFormSet 以验证相关表单。如果一切顺利,我的两个表格都将被保存,否则错误将显示在模板中。
查看
from django.shortcuts import render,redirect
from .forms import SignUpForm
from .formsets import StudentCreationFormSet
def createAccountView(request):
student_account_form = SignUpForm()
student_details_formset = StudentCreationFormSet()
if request.method == 'POST':
student_account_form = SignUpForm(request.POST)
if student_account_form.is_valid():
# Validating Custom User form and creating object of it(not comitting as formset needed to be verified)
student_account = student_account_form.save(commit=False)
# Getting Custom User object as passing it as instance to formset
student_details_formset = StudentCreationFormSet (request.POST,instance=student_account)
if student_details_formset.is_valid():
student_account_form.save()
student_details_formset.save()
return redirect('login')
else:
student_details_formset = StudentCreationFormSet (request.POST)
context = {
'student_account_form':student_account_form,
'student_details_form':student_details_formset
}
return render(request, 'account/createStudentPage.html',context=context)
另请注意,我在单个发布请求中同时传递了表单和表单集。
模板(createStudentPage.html)
<form method="POST" >
{% csrf_token %}
{{ student_account_form.as_p }}
{{ student_details_form.as_p }}
<button type="submit">Sign Up</button>
</form>