views:

99

answers:

0

I'm using django-profiles in my app, as it gives me a few simple views that helps me get where I want to go, faster.

However, I have one problem. Given the models below, how can I create a form for editing a profile that includes all the fields on UserProfile, the first_name, last_name and email fields from User, and one or more PhoneNumbers?

from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    height = models.IntegerField(_('Height'), max_length=3, blank=True, null=True, help_text=_('Users height in centimeters'))

    def get_absolute_url(self):
        return ('profiles_profile_detail', (), { 'username': self.user.username })
    get_absolute_url = models.permalink(get_absolute_url)

    def __unicode__(self):
        return self.user.username

class PhoneNumber(models.Model):
    description = models.CharField(_("Description"), max_length=32, blank=True)
    number = models.CharField(_("Phone number"), max_length=15)
    owner = models.ForeignKey(UserProfile, related_name="phone_numbers")

    def __unicode__(self):
        return u"%s (%s)" % (self.number, self.description)

The closest I've managed so far, is a form that includes all fields on UserProfile, and the wanted fields from User, using tricks explained here and here:

from django import forms
from main.models import UserProfile
from django.contrib.auth.models import User

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email')

class ProfileForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        # magic
        self.user = kwargs['instance'].user
        user_kwargs = kwargs.copy()
        user_kwargs['instance'] = self.user
        self.uf = UserForm(*args, **user_kwargs)
        # magic end

        super(ProfileForm, self).__init__(*args, **kwargs)

        self.fields.update(self.uf.fields)
        self.initial.update(self.uf.initial)

    def save(self, *args, **kwargs):
        # save both forms
        self.uf.save(*args, **kwargs)
        return super(ProfileForm, self).save(*args, **kwargs)

    class Meta:
        model = UserProfile
        exclude = ("user",)

In the admin, using Inlines on a custom ModelAdmin, I get the behaviour I want for the PhoneNumbers, but I've not been able to recreate it in a single form for use with django-profiles.

Is it at all possible, or should I just ditch django-profiles and write my own profile-app that can use a formset to pull in the PhoneNumbers?