【发布时间】:2011-10-12 21:04:06
【问题描述】:
我有一个名为Personnel 的模型,我将其用作User 模型的配置文件模型。这是我的模型
class Personnel(models.Model):
user = models.OneToOneField(
User
)
phone = models.CharField(
null=False, max_length=50, verbose_name="Phone"
)
我需要在 ModelForm 中使用上述模型。这是我的ModelForm:
class PersonnelForm(forms.ModelForm):
class Meta:
model = Personnel
exclude = ('user')
def __init__(self, *args, **kwargs):
personnel = Personnel(user=User.objects.create(username=(''.join(choice(ascii_uppercase + digits) for x in range(30)))))
super(PersonnelForm, self).__init__(
instance=personnel, *args, **kwargs
)
我不需要将user 字段显示在网络上,因此我将其排除在外。但是我仍然需要为它传递一个值,所以通过传递一个Personnel 实例来启动我的PersonnelForm。 User 模式有一个名为 email 的字段应该由用户输入,但我无法显示此字段,因为它不是我的 Personnel 模型上的字段。
我可以创建一个名为email 的虚拟字段,它在设置时设置user.email 字段的值,在获取时获取相同的值。像这样:
@property
def email():
def fget(self):
return 'fff'
def fset(self, email):
self.user.email = email
我需要以类似于上面的 sn-p 的方式使用它,因为我将使用 PersonnelForm 和 Django's generic CRUD views。
谢谢。
(请随时编辑并为标题建议一个更好的名称,以便其他人也能从中受益。)
使用丹尼尔的建议:
class PersonnelForm(forms.ModelForm):
email = forms.EmailField(
required=True, label=_("Email")
)
class Meta:
model = Personnel
exclude = ('user')
def save(self, *args, **kwargs):
commit = kwargs.get('commit', True)
kwargs['commit'] = False
personnel = super(PersonnelForm, self).save(*args, **kwargs)
if not personnel.user: #To prevent creating a new user when updating.
user = User.objects.create_user(
email=self.cleaned_data['email'],
username=(''.join(choice(ascii_uppercase + digits) for x in range(30))),
)
if commit:
personnel.save()
return personnel
这适用于使用 ModelForm 创建新记录,但我似乎无法更新电子邮件或在更新时查看电子邮件。
【问题讨论】:
-
您不需要为用户传递任何值,因为您已从 PersonnelForm 中排除了该属性。
-
Brandon,如果我不排除用户字段,那么它会在我的表单中为我提供一个下拉列表,用于创建
Personnel记录。我需要创建一个Personnel记录并在幕后自动创建一个User。每个User record都会有一个随机的username,password可以为空,稍后我会处理它,但我需要用户能够指定电子邮件地址——因此属性混乱。 -
我完全明白。您可以创建 User 对象并设置任何属性,而不会造成属性混乱。至少有 3 个地方可以创建 User 对象 - 在 Personnel 对象的 save 方法中、处理 Personnel 表单的视图中,甚至在附加到 Personnel 类的 post_save 信号中。
-
我无法编辑视图,因为它是 Django 内置的通用视图之一。我需要接受用户对电子邮件地址字段的输入,但这在我将该字段添加到我的模型之前不会显示。如果您查看我的代码,我已经在创建
User并将其作为实例传递给 ModelForm。我不需要用户输入用户名,因为它是随机生成的,但确实需要输入email。如果我没有电子邮件,我看不出post_save信号对我有什么帮助,自定义save方法也是如此。如果我在这里遗漏了什么并且听起来很愚蠢,请原谅我。 -
不用担心。您始终可以向模型表单添加与模型上的字段不对应的字段,例如您需要在人员表单上的电子邮件字段。您可以获取该值并将其应用于您的用户对象。
标签: python django django-models properties django-forms