How to create a UserProfile form in Django with first_name, last_name modifications?
If think my question is pretty obvious and almost every developer working with UserProfile
should be able to answer it.
However, I could not find any help on the django documentation or in the Django Book.
When you want to do a UserProfile
form in with Django Forms, you'd like to modify the profile fields as well as some User
field.
But there is no forms.UserProfileForm
(yet?)!
How do you do that?
Solution 1:
I stumbled across this today and after some googling I found a solution that is a bit cleaner in my opinion:
#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>
Source
Solution 2:
Here is how I finally did :
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
Solution 3:
This is how I did it in the current trunk (Revision: 11804). The solution of Natim was not working for me.
In 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()
In 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.]
Solution 4:
You can also try to use the django-basic-apps project which has a profiles app:
https://github.com/nathanborror/django-basic-apps