我有一个UserProfile
模型,它将OneToOne与Django User
模型相关联。在通过表单添加用户时,我希望为这两个表单添加一个表单。我发现了一个完全相同的代码片段,我没有遇到任何问题,直到我想验证username
。该表单不会像我希望的那样抛出ValidationError
,但会返回包含ValueError: The User could not be created because the data didn't validate.
的错误页面。
根据我的理解(显然可能是错误的),当前设置不会从嵌套表单处理ValidationError
。
有没有办法添加该功能?如果没有,我应该如何处理模型的一个表格处理问题?
代码:
class CmUserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(),
required=False,
help_text=_("Leave empty if you don't want "
"to change it"))
def clean_password(self):
data = self.cleaned_data['password']
if data.strip():
return make_password(data)
else:
# If password field is empty, then don't change it
return self.instance.password
def clean_username(self):
username = self.cleaned_data['username']
if get_user_model().objects.filter(username=username).exists():
raise forms.ValidationError(_('This username is already in use.'))
return username
class Meta:
model = get_user_model()
fields = ('first_name', 'last_name', 'email', 'username', 'password', 'is_staff', 'is_active')
class CmUserProfileForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
# Take User if updating, None if creating
try:
self.user = kwargs['instance'].user
except AttributeError:
self.user = None
user_kwargs = kwargs.copy()
user_kwargs['instance'] = self.user
self.uf = CmUserForm(*args, **user_kwargs)
super(CmUserProfileForm, self).__init__(*args, **kwargs)
self.fields.update(self.uf.fields)
self.initial.update(self.uf.initial)
class Meta:
model = UserProfile
exclude = ['user']
def save(self, *args, **kwargs):
# Save User and pass it to UserProfile
user = self.uf.save(*args, **kwargs)
self.instance.user = user
return super().save(*args, **kwargs)
答案 0 :(得分:1)
class Sam(models.Model):
user = model.OneToOneField(User)
#custom fields apart from the inbuilt User model
region = models.CharField(max_length=10)
designation = models.CharField(max_length=10)
#forms.py form models. Created SamProfileform to capture the custom fields which are specific to One's Profile and SamForm to capture the password and then hash later in the view.
#Please note that i didnt add any username check here. The inbuilt User does it for us. I verified it.
class SamForm(forms.ModelForm):
#form model to capture inbuilt fields of "User" model
password = forms.CharField(widget=PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'password', 'firstname', 'lastname')
class SamProfileForm(forms.ModelForm):
#form model to built the custom fields in my case region and designation
class Meta:
model = Sam
fields = ('desgination', 'mgr')
def register(request):
registered = False
if request.method == 'POST':
user_form = SamForm(data=request.POST)
profile_form = SamProfileForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
registered = True
else:
print user_form.errors, profile_form.errors
else:
user_form = SamForm()
profile_form = SamProfileForm()
template = loader.get_template('sam/register.html')
context = RequestContext(request, {
'user_form' : user_form, 'profile_form' : profile_form, 'registered' : registered,
})
return HttpResponse(template.render(context))