Как создать форму UserProfile в Django с модификациями first_name, last_name?
Если я думаю, что мой вопрос довольно очевиден, и почти каждый разработчик, работающий с UserProfile
, должен иметь возможность ответить на него.
Однако я не мог найти никакой помощи в документации django или в книге Django.
Если вы хотите сделать форму UserProfile
в Django Forms, вы хотите изменить поля профиля, а также некоторое поле User
.
Но нет forms.UserProfileForm
(еще?)!
Как вы это делаете?
Ответы
Ответ 1
Вот как я, наконец, сделал:
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
Я наткнулся на это сегодня, и после некоторых поисковых запросов я нашел решение, которое, по моему мнению, немного чище:
#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>
Источник
Ответ 3
Вот как я это сделал в текущем стволе (Revision: 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.]
Ответ 4
Вы также можете попытаться использовать проект django-basic-apps, в котором есть приложение для профилей:
https://github.com/nathanborror/django-basic-apps
Ответ 5
Это то, что я использовал в одном своем проекте долгое время, надеюсь, он должен помочь другим пользователям решить эту проблему.
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
Ответ 6
Я считаю, что вы не находите никакой информации в документах, когда вы объединяете две модели в одну форму.
В качестве альтернативы и, возможно, очень очевидно, что вы можете: Создайте две модели моделей: одну для пользователя и другую для пользовательского файла. Установите модель модели userprofile для отображения только имени и имени. Поместите обе формы в один шаблон в один тег <form>
. Когда он отправлен, вызовите методы сохранения для каждой формы.
Ответ 7
Почему у вас нет двух форм модели на заднем плане и просто представить их как одну форму в вашем шаблоне? Отбросить поля имени из UserProfileForm и создать вторую модельную форму для пользовательского объекта?