【问题标题】:Django Queryset in ModelForm using a 'pk'ModelForm 中的 Django Queryset 使用“pk”
【发布时间】:2018-11-14 09:47:24
【问题描述】:

我正在尝试关注this SO Q&A,这正是我想要做的,但使用 pk 而不是固定密钥。我的文件...

views.py

class JuryCreate(CreateView):
    model = Jury
    form_class = JuryCreateForm

    def form_valid(self, form):
        form.instance.customer_id = self.kwargs['pk']
        form.instance.court_year_id = self.kwargs['yr']
        return super().form_valid(form)

forms.py

class JuryCreateForm(ModelForm):

    class Meta:
        model = Jury
        fields = [
            'parent_jury',
            #Other Fields
            ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['parent_jury'].queryset = Jury.objects.filter(
            customer_id = self.kwargs['pk']).filter(
            court_year_id = self.kwargs['yr'])

如果我直接从view 转到模板,我就可以访问查询集(它提供了一个查询集对象)。但是如果我通过 ModelForm 它会抛出一个AttributeError: 'JuryCreateForm' object has no attribute 'kwargs'。基本上,我相信该请求没有传递给 ModelForm,因此它无法访问 kwargs。如何将主键放入 ModelForm 以填充字段?

我还尝试了 get_form_kwargs 方法的变体,我认为这是将这些传递给 ModelForm 的适当机制 - 我只是无法正确实现它(或在正确的类对象中得到它)。

【问题讨论】:

    标签: python django python-3.x django-forms


    【解决方案1】:

    尝试像这样覆盖视图的get_form_kwargs 方法:

    class JuryCreate(CreateView):
        model = Jury
        form_class = JuryCreateForm
    
        def form_valid(self, form):
            form.instance.customer_id = self.kwargs['pk']
            form.instance.court_year_id = self.kwargs['yr']
            return super().form_valid(form)
    
        def get_form_kwargs(self):
            kwargs = super().get_form_kwargs()
            kwargs['pk'] = self.kwargs['pk']
            kwargs['yr'] = self.kwargs['yr']
            return kwargs
    

    在表单初始化中使用kwargs['pk']kwargs.pop('pk') 访问pk 值:

    def __init__(self, *args, **kwargs):
        pk = kwargs.pop('pk')
        yr = kwargs.pop('yr') 
        super().__init__(*args, **kwargs)
        self.fields['parent_jury'].queryset = Jury.objects.filter(
            customer_id = pk).filter(
            court_year_id = yr)
    

    【讨论】:

    • 这会抛出:ModelFormMetaclass object argument after ** must be a mapping, not NoneType - 但我觉得这是在正确的轨道上 - 我只是无法让它正确通过。
    • @BillArmstrong 抱歉,我在get_form_kwargs 中错过了return kwargs。检查更新的答案。
    • Boom...是的-我缺少的是.pop(),然后在ModelForm类中删除了.self。谢谢。
    【解决方案2】:

    让模板工作

    作为@neverwalkaloner正确答案的最后后续——一旦在ModelForm中初始化了Queryset,它就会在模板中显示如下(或者至少是我找到的最快的方式):

    陪审团更新.html

    <select>
        {% for item in form.parent_jury.field.queryset %}
            <option value="{{item}}">{{ item }}</option>
        {% endfor %}
    </select>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-04
      • 1970-01-01
      • 2012-08-21
      • 2019-03-23
      • 2018-01-21
      • 2019-09-23
      • 2014-06-15
      • 2022-08-09
      相关资源
      最近更新 更多