Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 创建一个Django表单以保存两个模型_Python_Django_Django Models_Django Forms - Fatal编程技术网

Python 创建一个Django表单以保存两个模型

Python 创建一个Django表单以保存两个模型,python,django,django-models,django-forms,Python,Django,Django Models,Django Forms,我有常规的DjangoUser模型和UserDetails模型(OneToOneFieldwithUser),它是User模型的扩展。(我尝试了Django 1.5的功能,但它的文档异常糟糕,令人头痛,因此我坚持使用OneToOneField选项) 因此,在我试图构建一个自定义注册页面时,该页面将包含一个由User字段和UserDetails字段组成的注册表单,我想知道是否有一种方法可以从这两个相关模型中自动生成表单(及其所有验证)。我知道这适用于由一个模型制成的表单: class Meta:

我有常规的Django
User
模型和
UserDetails
模型(
OneToOneField
with
User
),它是
User
模型的扩展。(我尝试了Django 1.5的功能,但它的文档异常糟糕,令人头痛,因此我坚持使用
OneToOneField
选项)

因此,在我试图构建一个自定义注册页面时,该页面将包含一个由
User
字段和
UserDetails
字段组成的注册表单,我想知道是否有一种方法可以从这两个相关模型中自动生成表单(及其所有验证)。我知道这适用于由一个模型制成的表单:

class Meta:
    model = MyModel

但是,对于由两个相关模型组成的表单,是否还有类似的功能呢?

如果您想让用户和用户详细信息的模型表单保持分离,可以采用一种方法,即将两个表单返回前端,并确保它们都位于同一个html表单元素中(即,数据过账时将返回所有字段)

如果User和UserDetails没有任何同名字段,则可以使用此方法。要在每个ModelForm实例中输入数据,请使用通常的方法:

    form_user = UserForm(request.POST, instance=request.user)
    form_user_details = UserDetailsForm(request.POST, instance=request.user.userdetails)

是的,有,只需制作您自己的模型表单,您可以使用自定义保存fn在init函数中进行扩展。@Neal您能详细说明一下吗,如果可能的话,请举例说明,并将其作为答案发布,这样我就可以接受了?我不知道如何详细说明……我唯一想在答案中添加的内容就是我上面的评论中的内容……可能是duplicate of看起来不错,但是类Meta:model=UserDetails和not model=UserDetailsForm不应该吗?另外,假设UserDetails有一个名为phoneNumber的字段(带有\d{10}的regex),表单是否会自动处理您所说的这些问题(因为它与UserDetails模型链接)或者我需要修改上面的代码吗?谢谢我的错误。你必须修改它,因为我只为我看到的用户设置了公共字段。还有两个问题:1-如果我必须添加自定义用户详细信息字段(如电话),我应该在上面的代码中在哪里引用它,或者django会自动为我这样做,因为类meta现在指向UserDetails?2-其他用户字段(密码、用户名)呢?我必须将它们添加到您的代码中,还是Django会处理这些问题?1-您不必放置手机,因为表单meta已经指向UserDetails。2-您必须按照我在init函数中添加名字、姓氏和电子邮件的方式添加密码和用户名。因此init函数适用于您的用户模型,meta适用于您的UserDetails模型谢谢非常感谢。现在很清楚了。在注册过程中如何验证用户的电子邮件字段(并确保password1等于password2)?我想我也会这样做,对吧?记住用户还没有注册,不会请求。用户指向nothing(或匿名用户)?这是正确的,它将指向匿名用户。我只是展示了一个案例,您稍后将重新使用该表单。重复问题中的公认答案使用了此选项。我认为这样做更好,因为这样会减少出错的可能性。
from django.forms.models import model_to_dict, fields_for_model


class UserDetailsForm(ModelForm):
    def __init__(self, instance=None, *args, **kwargs):
        _fields = ('first_name', 'last_name', 'email',)
        _initial = model_to_dict(instance.user, _fields) if instance is not None else {}
        super(UserDetailsForm, self).__init__(initial=_initial, instance=instance, *args, **kwargs)
        self.fields.update(fields_for_model(User, _fields))

    class Meta:
        model = UserDetails
        exclude = ('user',)

    def save(self, *args, **kwargs):
        u = self.instance.user
        u.first_name = self.cleaned_data['first_name']
        u.last_name = self.cleaned_data['last_name']
        u.email = self.cleaned_data['email']
        u.save()
        profile = super(UserDetailsForm, self).save(*args,**kwargs)
        return profile