如何使用Django ModelForms中的self.field_value将查询集传递给ModelChoiceField

Sus*_*usa 11 django django-forms

我可以向你解释整个事情,但我猜一个代码比单词更清晰:

  class Skills(models.Model):
        skill = models.ForeignKey(ReferenceSkills)
        person = models.ForeignKey(User)

class SkillForm(ModelForm):
    class Meta:
        model = Skills
        fields = ( 'person', 'skill')
    (???)skill = forms.ModelChoiceField(queryset= SkillsReference.objects.filter(person = self.person)
Run Code Online (Sandbox Code Playgroud)

我只是猜测我该怎么做.但我希望你们明白我要做的事情.

Fal*_*gel 12

在创建表单实例之前,您可以对表单结构进行ovverride,如:

class SkillForm(ModelForm):
    class Meta:
        model = Skills
        fields = ( 'person', 'skill')
Run Code Online (Sandbox Code Playgroud)

在你看来:

SkillForm.base_fields['skill'] = forms.ModelChoiceField(queryset= ...)
form = SkillForm()
Run Code Online (Sandbox Code Playgroud)

您可以在视图中随时覆盖它,有些部分是,您必须在创建表单实例之前执行此操作

form = SkillForm()
Run Code Online (Sandbox Code Playgroud)


Vic*_*nes 6

假设您使用的是基于类的视图,您可以在表单 kwargs 中传递查询集,然后在表单 init 方法中替换它:

# views.py
class SkillUpdateView(UpdateView):
    def get_form_kwargs(self, **kwargs):
        kwargs.update({
            'skill_qs': Skills.objects.filter(skill='medium')
        })

        return super(self, SkillUpdateView).get_form_kwargs(**kwargs)


# forms.py
class SkillForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        qs = kwargs.pop('skill_ks')
        super(self, SkillForm).__init__(*args, **kwargs)

        self.fields['skill'].queryset = qs
Run Code Online (Sandbox Code Playgroud)

但是,我个人更喜欢第二种方法。我在视图上获取表单实例,然后在 django 将其包装在上下文之前替换字段查询集:

# views.py
class SkillsUpdateView(UpdateView):
    form_class = SkillForm

    def get_form(self, form_class=None):
        form = super().get_form(form_class=self.form_class)
        form.fields['skill'].queryset = Skills.objects.filter(skill='medium')

        return form
Run Code Online (Sandbox Code Playgroud)