0

Lets say I need to filter the options available in a multiple select box.

in my view I have:

class ArticleCheckbox(forms.ModelForm):
    article= forms.ModelMultipleChoiceField(queryset=Article.objects.all(),required=False, widget=forms.CheckboxSelectMultiple)
    class Meta:
        model = Book
        fields = ('m2m_article',)

. In my view I will assign:

articleform = ArticleCheckbox()
articleform.fields["m2m_article"].queryset = Article.objects.filter(category = "Animals")

How does the assigning of the queryset in the view affect the queryset from classes (Article.object.all()) ? Does it overwrite? I do not think so.

I would like to override the queryset. How can I do it?

caliph
  • 1,389
  • 3
  • 27
  • 52

2 Answers2

0

Does this work?

article=forms.ModelMultipleChoiceField(queryset=Article.objects.all().filter(category = "Animals"),required=False, widget=forms.CheckboxSelectMultiple)

Directly in the model. Or do you want to leave the filtering to the view to do different things?

Raphaël Gomès
  • 938
  • 1
  • 8
  • 23
  • I need to do it in the view after the class has been constructed. I need different filters. The above static example is only an example. Im my code the filter is dynamic. – caliph Dec 01 '15 at 08:01
  • Best solution I could image would be to pass the filter criterium for form construction. But even if I pass a variable to the model form, I cannot use it before construction. That means I can not set the filter dynamically like in your example. Or am I wrong? – caliph Dec 01 '15 at 08:04
  • I agree with what Sayse said about providing a method pre-request to the model. – Raphaël Gomès Dec 01 '15 at 11:19
0

The way you're doing it is correct, except for you assign the class and not an instance of ArticleCheckBox

articleform = ArticleCheckbox()

When the form is initialised it is given a default queryset and you are overriding it, the initial one will never query the database since no data is ever needed to be retrieved at that point.

Sayse
  • 42,633
  • 14
  • 77
  • 146
  • Note: This answer is on the proviso that you only intend to do this from one function, if you want this default behaviour then do so either as your set default or perhaps in an initializer – Sayse Nov 30 '15 at 22:32
  • Thanks for the hint, I corrected the typo in my example. – caliph Dec 01 '15 at 07:55
  • When I do such an override, the HTML reflects only the filter from the view. Unfortunately the POST response (uncleaned) has ALL the options. Without the overriding filter! Thats is very unfortunate because when object.save() is applied all not shown options are being unselected in the database. – caliph Dec 01 '15 at 07:58
  • @caliph - This is what I meant in my last paragraph (sentence), you should provide an `__init__` method and set the filter in there, or some other method that must get called before the post response is returned – Sayse Dec 01 '15 at 08:02