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

问题描述

| 我可以向您解释整个过程,但是我猜代码比单词更清晰,所以:
  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)
我只是在猜我该怎么做。但是我希望你们能理解我正在尝试做的事情。     

解决方法

        您可以先创建一个表单结构,然后再创建一个表单实例,例如:
class SkillForm(ModelForm):
    class Meta:
        model = Skills
        fields = ( \'person\',\'skill\')
您认为:
SkillForm.base_fields[\'skill\'] = forms.ModelChoiceField(queryset= ...)
form = SkillForm()
您可以随时在视图中覆盖它,重要的一点是,必须先创建它,然后才能使用
form = SkillForm()
    ,        假设您正在使用基于类的视图,则可以在表单kwargs中传递queryset,然后将其替换为表单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
但是,我个人更喜欢第二种方法。我在View上获取表单实例,然后在django将其包装到上下文之前替换字段queryset:
# 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
    ,        您的代码看起来几乎没问题。试试这个技能表:
class SkillForm(ModelForm):
    skill = forms.ModelChoiceField(queryset= SkillsReference.objects.filter(person = self.person)
    class Meta:
        model = Skills
        fields = ( \'person\',\'skill\')
区别在于技能是表单的领域,不应在Meta类中 已编辑 上面的解决方案是错误的,但是此链接描述了如何实现您想要的: http://www.zoia.org/blog/2007/04/23/using-dynamic-choices-with-django-newforms-and-custom-widgets/