【问题标题】:How to pass a queryset to a ModelChoiceField using a self.field_value in Django ModelForms如何使用 Django ModelForms 中的 self.field_value 将查询集传递给 ModelChoiceField
【发布时间】:2011-05-27 11:52:37
【问题描述】:

我可以向你解释整个事情,但我想代码比文字更清楚,所以:

  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)

我只是在猜测我该怎么做。但我希望你们能理解我想要做什么。

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    您可以在创建表单实例之前覆盖表单结构,例如:

    class SkillForm(ModelForm):
        class Meta:
            model = Skills
            fields = ( 'person', 'skill')
    

    在你看来:

    SkillForm.base_fields['skill'] = forms.ModelChoiceField(queryset= ...)
    form = SkillForm()
    

    您可以随时在视图中覆盖它,重要的是,您必须在使用

    创建表单实例之前执行此操作
    form = SkillForm()
    

    【讨论】:

    • 在您看来,不要忘记导入“from django import forms”之类的表单
    【解决方案2】:

    假设您使用的是基于类的视图,您可以在表单 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
    

    但是,我个人更喜欢第二种方法。我在视图上获取表单实例,然后在 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
    

    【讨论】:

      【解决方案3】:

      您的代码看起来几乎没问题。试试这个 SkillForm:

      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/

      【讨论】:

      • 链接失效
      猜你喜欢
      • 1970-01-01
      • 2014-11-15
      • 2013-03-14
      • 2017-11-25
      • 1970-01-01
      • 2016-12-31
      • 2013-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多