使用django-profiles以配置文件形式编辑相关模型

时间:2010-09-05 00:15:32

标签: python django django-forms

我在我的应用中使用django-profiles,因为它为我提供了一些简单的视图,帮助我更快地到达目的地。

但是,我有一个问题。根据以下模型,如何创建用于编辑配置文件的表单,其中包含UserProfile上的所有字段,User中的first_name,last_name和电子邮件字段,以及一个或多个PhoneNumber S'

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)

我到目前为止管理的最接近的表单是包含UserProfile上所有字段的表单,以及来自User的所需字段,使用说明here和{{3}的技巧}:

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",)

在管理员中,在自定义ModelAdmin上使用Inlines,我得到了PhoneNumber所需的行为,但我无法在单个表单中重新创建它以与django-profiles一起使用。

是否可能,或者我应该抛弃django-profiles并编写我自己的profile-app,它可以使用formset来引入PhoneNumber

2 个答案:

答案 0 :(得分:1)

将两个模型填充到同一个表单中是一种相当大的扭曲。选择:

  • 制作您自己的观点。您可以利用django网址的短路,先到先得的性质来盗取那个。

  • 将django-profiles添加到您自己的版本控件中,并在不受可重用性约束的情况下将其破解为您的内容。

  • 您可以使用自己的保存方法创建一个大表单,并使用django-profiles。这比仅仅声明fields = ('first_name', 'last_name', 'email')exclude = ("user",)更加繁琐。 See the docstrings

取决于该项目。我肯定会想写自己的。配置文件应用程序并不多,您可能会遇到其他希望您拥有更多控制权的地方。

答案 1 :(得分:1)

据我所知,django-profiles绝对是一个美化的观点。我添加到我的应用程序但遇到了同样的问题。对源代码的检查表明它基本上没有特征。基本上,它可以帮您省去编写自己的edit_profilecreate_profile视图的麻烦。真的,就是这样。除非您对编写自己的视图感到非常恐惧,否则不要使用django-profiles,只需滚动自己的代码。