user9252255
user9252255

Reputation:

Django: Forms Queryset

I wonder if that is the right approach. I first call queryset=Reward.objects.all() just to change it right after and filter it. However, I couldn't come up with a better solution. Do you have any thoughts on that?

   class ClaimRewardForm(forms.ModelForm):
        note = forms.CharField(widget=forms.Textarea)
        title = forms.ModelChoiceField(queryset=Reward.objects.all())
        # note = forms.DropDown()

        class Meta:
            model = Reward
            fields = ['title']

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.fields['title'].queryset = Reward.objects.filter(event=self.initial['event'])

Upvotes: 0

Views: 1137

Answers (2)

Pavel Minenkov
Pavel Minenkov

Reputation: 403

If you should process set of models, try change your approach to FormSets https://docs.djangoproject.com/en/2.0/topics/forms/formsets/

Briefly, FormSets approach seem so: 1. Declare ClaimRewardForm class for single model (Reward in your case) 2. Declare ClaimRewardFormSet for ClaimRewardForm with overriding

class BaseClaimRewardFormSet(BaseModelFormSet):

    """By default, when you create a formset from a model, the formset
    will use a queryset that includes all objects in the model"""

    def __init__(self, *args, **kwargs):
        if 'event' in kwargs.keys():
            event = kwargs.pop('event')
        else:
            event = None
        super().__init__(*args, **kwargs)
        if event is not None:
            self.queryset = Reward.objects.filter(event=event)
        else:
            self.queryset = Reward.objects.none()


ClaimRewardFormSet = forms.modelformset_factory(Reward, RewardForm, 
formset=BaseClaimRewardFormSet) 

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599450

That queryset is never evaluated, because you always replace it on instantiation, so it doesn't really matter what you put there.

One alternative night be to use Reward.objects.none() to indicate that it's never used.

Upvotes: 1

Related Questions