开发者

How to pass a queryset to a ModelChoiceField using a self.field_value in Django ModelForms

开发者 https://www.devze.com 2023-03-08 23:19 出处:网络
I could explain the whole thing to you but I guess a code speaks clearer than words so: class Skills(models.Model):

I could explain the whole thing to you but I guess a code speaks clearer than words so:

  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= Skil开发者_如何学GolsReference.objects.filter(person = self.person)

I'm just guessing at how I can do it. But I hope you guys understand what I'm trying to do.


You can ovverride a form structure before you create an instance of the form like:

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

In your view:

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

You can override it anytime you want in your view, impottant part is, you must do it before creating your form instance with

form = SkillForm()


Assuming you are using class-based views, you can pass the queryset in your form kwargs and then replace it on form init method:

# 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

But, personally I prefer this second approach. I get the form instance on the View and than replace the field queryset before django wrap it on the context:

# 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


Your code looks almost ok. Try this SkillForm:

class SkillForm(ModelForm):
    skill = forms.ModelChoiceField(queryset= SkillsReference.objects.filter(person = self.person)
    class Meta:
        model = Skills
        fields = ( 'person', 'skill')

The difference is that skill is a form's field, should not be in Meta class

EDITED

The above solution is incorrect, but this link describes how to achieve what you want: http://www.zoia.org/blog/2007/04/23/using-dynamic-choices-with-django-newforms-and-custom-widgets/

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号