【问题标题】:django: use a queryset as modelform initial datadjango:使用查询集作为模型形式的初始数据
【发布时间】:2012-07-14 14:25:54
【问题描述】:

我正在制作一个设置界面,它通过扫描已安装应用程序中的设置文件夹、扫描设置文件,最后扫描 ModelForms 来工作。

我现在处于最后一步。表格已正确找到并加载,但我现在需要提供初始数据。初始数据将从数据库中提取,并且可以想象,它必须仅限于经过身份验证的用户(通过 request.user.id)。

请记住,这一切都是动态完成的。没有任何东西的名称,也没有它们的高级结构(我真的不想维护一个无聊的设置界面)。

这是一个示例设置表单。我只是选择模型和用户可以编辑的字段(这是我想要维护设置界面的程度)。

class Set_Personal_Info(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('nick_name', 'url')

我查看了modelformset_factory,它几乎做了我想做的事,但它似乎只适用于两个或更多的结果。 (这里obj是设置形式之一)

Formset = modelformset_factory(obj.Meta.model, form=obj)
Formset(queryset=obj.Meta.model.objects.filter(id=request.user.id))

我无法过滤数据,我必须得到一个,而且只有一个结果。不幸的是我不能使用 get()

Formset = modelformset_factory(obj.Meta.model, form=obj)
Formset(queryset=obj.Meta.model.objects.get(id=request.user.id))

“用户”对象没有“有序”属性

将查询结果作为初始数据提供也不起作用,因为它不是列表。

Formset = modelformset_factory(obj.Meta.model, form=obj)
Formset(initial=obj.Meta.model.objects.get(id=request.user.id))

“用户”对象不支持索引

我感觉答案就在我面前。如何从数据库中提取数据库并将其作为初始值推入表单?

【问题讨论】:

    标签: django


    【解决方案1】:

    根据我的理解......如果你想生成一个带有动态字段的表单,你可以使用这个:

    类 MyModelForm(forms.ModelForm):

    def __init__(self, dynamic_fields, *args, **kwargs):
        super(MyModelForm, self).__init__(*args, **kwargs)
    
        self.fields = fields_for_model(self._meta.model, dynamic_fields, self._meta.exclude, self._meta.widgets)
    
        class Meta:
            model = MyModel
    

    其中 dynamic_fields 是一个元组。

    关于动态表单的更多信息:

    1. http://www.rossp.org/blog/2008/dec/15/modelforms/
    2. http://jacobian.org/writing/dynamic-form-generation/
    3. http://dougalmatthews.com/articles/2009/dec/16/nicer-dynamic-forms-django/

    Daniel 的方法也是有效且干净的......根据您不同的 ids/types 等,您可以使用不同的 Form 对象

    forms.py

    类 MyModelFormA(forms.ModelForm):

    class Meta:
        model = MyModel
        fields = ('field_a','field_b','field_c')
         class MyModelFormB(forms.ModelForm):
    
    class Meta:
        model = MyModel
        fields = ('field_d','field_e','field_f')
    

    views.py

    如果 request.method == 'POST':

    if id == 1:
        form = MyModelFormA(data=request.POST)
    elif id == 2:
        form = MyModelFormB(data=request.POST)
    else:
        form = MyModelFormN(data=request.POST)
    
    if form.is_valid():
        form.save() else:
    if id == 1:
        form = MyModelFormA()
    elif id == 2:
        form = MyModelFormB()
    else:
        form = MyModelFormN()
    

    【讨论】:

      【解决方案2】:

      我不确定我是否理解您想要做什么 - 如果您只对单个表单感兴趣,我完全不知道您为什么要参与表单集。

      要使用数据库中的初始数据填充模型表单,您只需传递实例参数:

      my_form = Set_Personal_Info(instance=UserProfile.objects.get(id=request.user.id))
      

      不要忘记在 POST 上实例化表单时也传递实例参数,以便 Django 更新现有实例而不是创建新实例。

      (请注意,您可能需要考虑为您的对象提供更好的名称。obj 通常描述一个模型实例,而不是一个表单,form 将是一个更好的名称。表单类应该遵循 PEP8,并且可能包含“表单”这个词 - 所以PersonalInfoForm 会是个好名字。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-11
        • 2015-06-14
        • 2016-05-02
        • 1970-01-01
        • 1970-01-01
        • 2012-12-15
        • 2020-11-14
        相关资源
        最近更新 更多