Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/365.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.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 Forms - Fatal编程技术网

Python django模型形式。包括相关模型中的字段

Python django模型形式。包括相关模型中的字段,python,django,django-forms,Python,Django,Django Forms,我有一个名为Student的模型,它有一些字段,和一个用户(django.contrib.auth.user)的OneToOne关系 然后,我有一个该模型的模型表单 class StudentForm (forms.ModelForm): class Meta: model = Student 使用Meta类中的fields属性,我成功地在模板中只显示了一些字段。但是,我可以指出要显示哪些用户字段吗 例如: fields =('personalInfo','use

我有一个名为Student的模型,它有一些字段,和一个用户(django.contrib.auth.user)的OneToOne关系

然后,我有一个该模型的模型表单

class StudentForm (forms.ModelForm):
    class Meta:
        model = Student
使用Meta类中的fields属性,我成功地在模板中只显示了一些字段。但是,我可以指出要显示哪些用户字段吗

例如:

   fields =('personalInfo','user.username')
目前没有显示任何内容。但仅适用于StudentFields/


提前感谢。

两个答案都是正确的:内联表单集使这项工作变得简单

但是,请注意,内联只能走一条路:从包含外键的模型开始。如果两个主键中都没有主键(不好,因为可以有A->B,然后是B->A2),则不能在相关的模型中有内联表单集

例如,如果您有一个UserProfile类,并且希望能够在显示这些类时,将相关的用户对象显示为内联的,那么您就不走运了


您可以在模型表单上设置自定义字段,并将其作为一种更灵活的方式使用,但请注意,它不再像标准模型表单/内联表单集那样是“自动”的。

一种常见做法是使用两个表单来实现您的目标

  • 用户
    模型的表格:

    class UserForm(forms.ModelForm):
        ... Do stuff if necessary ...
        class Meta:
            model = User
            fields = ('the_fields', 'you_want')
    
    class StudentForm (forms.ModelForm):
        ... Do other stuff if necessary ...
        class Meta:
            model = Student
            fields = ('the_fields', 'you_want')
    
  • 学生
    模型的表格:

    class UserForm(forms.ModelForm):
        ... Do stuff if necessary ...
        class Meta:
            model = User
            fields = ('the_fields', 'you_want')
    
    class StudentForm (forms.ModelForm):
        ... Do other stuff if necessary ...
        class Meta:
            model = Student
            fields = ('the_fields', 'you_want')
    
  • 在视图中同时使用这两种形式(用法示例):

  • 在模板中一起呈现表单:

    <form action="." method="post">
        {% csrf_token %}
        {{ user_form.as_p }}
        {{ student_form.as_p }}
        <input type="submit" value="Submit">
    </form>
    
    
    {%csrf_令牌%}
    {{user_form.as_p}
    {{student_form.as_p}}
    


另一种选择是,您可以将关系从
OneToOne
更改为
ForeignKey
(这完全取决于您,我只是提一下,不推荐)你可以考虑的另一种方法是通过扩展抽象用户或抽象用户模型来创建一个定制的用户模型,而不是使用一个带有配置文件模型的模型(在这种情况下是学生模型)。这将创建一个扩展用户模型,您可以使用该模型创建一个ModelForm

例如,一种方法是扩展:

在管理员中更新模型:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import Student

admin.site.register(Student, UserAdmin)
然后,您可以使用一个ModelForm,该ModelForm既包含所需的附加字段,也包含原始用户模型中的字段。在forms.py中

from .models import Student    

class StudentForm (forms.ModelForm):
    class Meta:
        model = Student
        fields = ['personalInfo', 'username']
更复杂的方法是扩展AbstractBaseUser,这一点已详细描述


然而,我不确定以这种方式创建自定义用户模型以获得一个方便的单一ModelForm是否适合您的用例。这是您必须做出的设计决策,因为创建自定义用户模型可能是一项棘手的工作。

据我所知,您希望更新auth.User的用户名字段,该字段是与
学生
的关系

class StudentForm (forms.ModelForm):

username = forms.Charfield(label=_('Username'))
class Meta:
    model = Student
    fields = ('personalInfo',)

def clean_username(self):
    # using clean method change the value
    # you can put your logic here to update auth.User
    username = self.cleaned_data('username')
    # get AUTH USER MODEL
    in_db = get_user_model()._default_manager.update_or_create(username=username)

希望这能有所帮助:)

我正好碰到了这个问题和您的答案中描述的问题。现在很多年过去了。你知道现在是否有一个自动的解决方案吗?@cel我不知道“自动”方式(正如你所说的),但我在这个答案中有一个手动的解决方案。看一看:)我不确定这是你想要的,但是你可以看一看如果学生模型继承了用户模型,你只需要一个模型形式。@KevinL.,如果你在回答中详细说明这一点就好了:-)@cel AFAIK,Django core中没有这样的发展。这里的“自动”解决方案可能非常重要,需要编写您自己的定制modelform类或mixin来实现。这比使用建议的方法要复杂得多(也可能更脆弱)。一个可能的解决方案可能包含在其中,它描述了一个ModelForm mixin,允许定义第二个“子”模型,并声称与通用视图兼容。嘿,@Tom,我在想,你觉得有什么答案有用吗?这怎么知道要更新哪个用户对象?
from .models import Student    

class StudentForm (forms.ModelForm):
    class Meta:
        model = Student
        fields = ['personalInfo', 'username']
class StudentForm (forms.ModelForm):

username = forms.Charfield(label=_('Username'))
class Meta:
    model = Student
    fields = ('personalInfo',)

def clean_username(self):
    # using clean method change the value
    # you can put your logic here to update auth.User
    username = self.cleaned_data('username')
    # get AUTH USER MODEL
    in_db = get_user_model()._default_manager.update_or_create(username=username)