ModelForm中的Django Queryset使用'pk'

时间:2018-06-05 02:10:59

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

我正在尝试关注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的合适机制 - 我无法让它正确实现(或者在正确的类对象中获取它)

2 个答案:

答案 0 :(得分:2)

尝试覆盖视图的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

在表单init中使用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)

答案 1 :(得分:1)

让模板正常工作

作为@neverwalkaloner正确答案的最终后续 - 一旦在ModelForm中初始化Queryset,它就会在模板中显示如下(或者至少是我发现的最快的方式):< / p>

陪审团update.html

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