如果认为我的问题很明显,几乎每个使用UserProfile
的开发人员都应该能够回答它。
但是,我在django文档或Django Book中找不到任何帮助。
如果您想在Django Forms中使用UserProfile
表单,则需要修改配置文件字段以及一些User
字段。
但是没有forms.UserProfileForm
(还有?)!
你是怎么做到的?
答案 0 :(得分:37)
今天我偶然发现了这一点,经过一些谷歌搜索后,我发现了一个在我看来更清洁的解决方案:
#in forms.py
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ["username", "email"]
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
#in views.py
def add_user(request):
...
if request.method == "POST":
uform = UserForm(data = request.POST)
pform = UserProfileForm(data = request.POST)
if uform.is_valid() and pform.is_valid():
user = uform.save()
profile = pform.save(commit = False)
profile.user = user
profile.save()
....
...
#in template
<form method="post">
{{ uform.as_p }}
{{ pform.as_p }}
<input type="submit" ...>
</form>
答案 1 :(得分:34)
以下是我最终的做法:
class UserProfileForm(forms.ModelForm):
first_name = forms.CharField(label=_(u'Prénom'), max_length=30)
last_name = forms.CharField(label=_(u'Nom'), max_length=30)
def __init__(self, *args, **kw):
super(UserProfileForm, self).__init__(*args, **kw)
self.fields['first_name'].initial = self.instance.user.first_name
self.fields['last_name'].initial = self.instance.user.last_name
self.fields.keyOrder = [
'first_name',
'last_name',
...some_other...
]
def save(self, *args, **kw):
super(UserProfileForm, self).save(*args, **kw)
self.instance.user.first_name = self.cleaned_data.get('first_name')
self.instance.user.last_name = self.cleaned_data.get('last_name')
self.instance.user.save()
class Meta:
model = UserProfile
答案 2 :(得分:5)
这就是我在当前主干中的做法(修订版:11804)。 Natim的解决方案对我不起作用。
在admin.py
:
class ProfileAdmin(admin.ModelAdmin):
form = ProfileForm
def save_model(self, request, obj, form, change):
obj.user.first_name = form.cleaned_data['first_name']
obj.user.last_name = form.cleaned_data['last_name']
obj.user.save()
obj.save()
在forms.py
:
class ProfileForm(forms.ModelForm):
first_name = forms.CharField(max_length=256)
last_name = forms.CharField(max_length=256)
def __init__(self, *args, **kwargs):
super(ProfileForm, self).__init__(*args, **kwargs)
try:
self.fields['first_name'].initial = self.instance.user.first_name
self.fields['last_name'].initial = self.instance.user.last_name
except User.DoesNotExist:
pass
class Meta:
fields = ['first_name', 'last_name', ...etc.]
答案 3 :(得分:1)
您还可以尝试使用具有配置文件应用程序的django-basic-apps项目:
答案 4 :(得分:1)
这是我长期以来在我的项目中使用的东西,希望它可以帮助其他人搜索这个问题。
class SignUpForm(forms.ModelForm):
first_name = forms.CharField(max_length = 30)
last_name = forms.CharField(max_length = 30)
username = forms.CharField(max_length = 30)
password = forms.CharField(widget = forms.PasswordInput)
password1 = forms.CharField(widget = forms.PasswordInput)
class Meta:
model = UserProfile
exclude = ['user']
def clean_username(self): # check if username does not exist before
try:
User.objects.get(username=self.cleaned_data['username']) #get user from user model
except User.DoesNotExist :
return self.cleaned_data['username']
raise forms.ValidationError("This user exist already choose an0ther username")
def clean(self, *args , **kwargs):
super(SignUpForm).clean(*args ,**kwargs) # check if password 1 and password2 match each other
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:#check if both pass first validation
if self.cleaned_data['password1'] != self.cleaned_data['password2']: # check if they match each other
raise forms.ValidationError("Passwords don't match each other")
return self.cleaned_data
def save(self): # create new user
new_user = User.objects.create_user(username=self.cleaned_data['username'],password=self.cleaned_data['password1'],email=self.cleaned_data['email'])
new_user.first_name = self.cleaned_data['first_name']
new_user.last_name = self.cleaned_data['last_name']
new_user.save()
UserProf = super(SignUpForm,self).save(commit = False)
UserProf.user = new_user
UserProf.save()
return UserProf
答案 5 :(得分:0)
我认为在将两个模型合并为一个表单时,在文档中找不到任何信息是正常的。
另外,也许很明显你可以:创建两个模型,一个用于用户,另一个用于用户配置文件。将userprofile modelform设置为仅显示firstname和lastname。将两个表单放在一个<form>
标记内的同一模板中。提交时,请调用每个表单的保存方法。
答案 6 :(得分:0)
为什么后端没有两个模型表单,只是在模板中将它们作为单个表单显示?从UserProfileForm中删除名称字段,并为用户对象创建第二个模型表单?