views:

228

answers:

2

So I have a model with a ManyToManyField called tournaments. I have a ModelForm with two tournament fields:

pay_tourns = forms.ModelMultipleChoiceField(
                        queryset=Tourn.objects.all().active().pay_tourns(),
                        widget=forms.CheckboxSelectMultiple())
rep_tourns = forms.ModelMultipleChoiceField(
                        queryset=Tourn.objects.all().active().rep_tourns(),
                        widget=forms.CheckboxSelectMultiple())

The methods after all() there are from a subclassed QuerySet. When I'm saving the form in my view I do thus:

post.tournaments = (post_form.cleaned_data.get('pay_tourns')
                                + post_form.cleaned_data.get('rep_tourns'))

Anyway, this all works fine. What I can't figure out how to do is fill these form fields out when I'm loading an existing post. That is, when I pass instance=post to the form. Any ideas?

+2  A: 

You could do something like this to the ModelForm:

def __init__(self, *args, **kwargs):
    super(MyForm, self).__init__(*args, **kwargs)

    instance = kwargs.get('instance')
    if instance:
        self.fields['pay_tourns'].queryset.filter(post=instance)
        self.fields['rep_tourns'].queryset.filter(post=instance)

I don't see why that wouldn't work, but I'm going to test it just to make sure...

EDIT: Tested and it works.

Paolo Bergantino
that works, but it doesn't do what I need. Rather then limiting the queryset, I need to have the ones that are associated with the post checked. What this does is make sure that only the tourns that are associated with the post are options.
defrex
Oooo, ok. one second then...
Paolo Bergantino
+1  A: 

Paolo Bergantino was on the right track, and helped me find it. This was the solution:

def __init__(self, *args, **kwargs):
    super(MyForm, self).__init__(*args, **kwargs)

    instance = kwargs.get('instance')
    if instance:
        self.fields['pay_tourns'].initial = [ o.id for o in instance.tournaments.all().active().pay_tourns()]
        self.fields['rep_tourns'].initial = [ o.id for o in instance.tournaments.all().active().rep_tourns()]
defrex
Nice solution, good to know. :)
Paolo Bergantino