Question

Let's say I have a model as follows.

models.py

class Profile(models.Model):
    user = models.OneToOneField(User)
    middle_name = models.CharField(max_length=30, blank=True, null=True)

And I have a custom field email as follows in a ModelForm

forms.py

class ProfileForm(ModelForm):
    email = forms.CharField()
    class Meta:
         model = models.Profile

    fields = ('email', 'middle_name')

In the am setting an instance of the above mentioned modelform so the data is prefilled in the form for an edit template as follows.

views.py

def edit_profile(request):
    profile = models.Profile.objects.get(user=request.user)
    profileform = forms.ProfileForm(instance=profile)
    return render_to_response('edit.html', { 'form' : 'profileform' }, context_instance=RequestContext(request))

Now in the form I get all the values prefilled for all the fields under Profile model but the custom fields are empty and it makes sense.

but is there a way I can prefill the value of the custom fields ? maybe something like:

email = forms.CharField(value = models.Profile.user.email)
Was it helpful?

Solution

Can I suggest something else? I'm not a huge fan of having that email field within a ModelForm of Profile if it has nothing to do with that model.

Instead, how about just having two forms and passing in initial data to your custom one containing email? So things would look like this:

forms.py

# this name may not fit your needs if you have more fields, but you get the idea
class UserEmailForm(forms.Form):
    email = forms.CharField()

views.py

profile = models.Profile.objects.get(user=request.user)
profileform = forms.ProfileForm(instance=profile)
user_emailform = forms.UserEmailForm(initial={'email': profile.user.email})

Then, you're validating both the profile and user email form, but otherwise things are mostly the same.

I assume you are not sharing logic between the Profile ModelForm and this UserEmailForm. If you need profile instance data, you could always pass that in there.

I prefer this approach because it's less magical and if you look back at your code in a year, you won't be wondering why, in brief scanning, why email is part of the ModelForm when it does not exist as a field on that model.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top