1
votes

In my Django project i create an app to have additional information about registered users. So my model looks like this:

class UserProfile(models.Model):
   class Meta:
      verbose_name_plural = u'User Profile'

   user = models.OneToOneField(User)
   birthday = models.DateField(blank=True, null=True)
   avatar = models.ImageField(upload_to='media/profile/avatar', blank=True, null=True)
   name = models.CharField(blank=True, null=True, max_length=20)
   surname = models.CharField(blank=True, null=True, max_length=50)
   phone = models.CharField(blank=True, null=True, max_length=12)

   def __unicode__(self):
      return '%s' % self.user

In user profile i create modelform where user can fill or edit the fields from UserProfile model:

class ExtraProfileDataForm(ModelForm):
   name = forms.CharField(label=(u'Enter your name'))
   surname = forms.CharField(label=(u'Enter your surname'))
   phone = forms.CharField(label=(u'Enter your phone'))
   birthday = forms.DateField(label=(u'Enter birthday'))
   avatar = forms.ImageField(label=(u'Enter avatar'))

   class Meta:
      model = UserProfile
      fields = ('name', 'surname', 'phone', 'birthday', 'avatar')

   def __init__(self, *args, **kwargs):
      super(ExtraProfileDataForm, self).__init__(*args, **kwargs)
         for key in self.fields:
            self.fields[key].required = False

This is the view of the model form:

@login_required
def UserFullDataForm(request):
   if request.method == 'POST':
      form = ExtraProfileDataForm(request.POST)
         if form.is_valid():
            profile_user = request.user
            user_profile = UserProfile(user=profile_user)
            user_profile.name = form.cleaned_data['name']
            user_profile.surname = form.cleaned_data['surname']
            user_profile.phone = form.cleaned_data['phone']
            user_profile.birthday = form.cleaned_data['birthday']
            user_profile.avatar = form.cleaned_data['avatar']
            user_profile.save()
            return HttpResponseRedirect('/profile/')
          else:
            return render(request, 'profiles/extra_profile.html', {'form':form})
        else:
            form = ExtraProfileDataForm()
            context = {'form':form}
            return render (request, 'profiles/extra_profile.html', context)

But i want to load on ExtraProfileDataForm initial data from model UserProfile if the fields not empty. I searched how to do that on Django documentation website, but nothing found. Can somebody help me to understand how to do it? Thanks a lot.

1

1 Answers

3
votes

You use the instance parameter.

Note that you are doing much more work than necessary here; most of your view can be cut.

@login_required
def UserFullDataForm(request):
    try:
        profile = request.user.userprofile
    except UserProfile.DoesNotExist:
        profile = UserProfile(user=request.user)

    if request.method == 'POST':
        form = ExtraProfileDataForm(request.POST, instance=profile)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/profile/')
        else:
            form = ExtraProfileDataForm(instance=profile)
        return render(request, 'profiles/extra_profile.html', {'form':form})

Similarly, in your form, you don't need the overridden __init__ method because you're manually specifying all the fields anyway; you can add required=False on each one there. However, you could make this even shorter by adding the labels in the model definition; then your entire modelform could just be:

class ExtraProfileDataForm(ModelForm):
    class Meta:
        model = UserProfile
        fields = ('name', 'surname', 'phone', 'birthday', 'avatar')

One final note: you're consistently using three-space indentation, which is a bit, well, odd. Most Python programmers prefer two or four.