Question

In a ModelForm, how can I filter a Select widget content with only values related with current instance? (The instance which called the ModelForm)

For example:

class smsForm(ModelForm):

    class Meta:
        model = SMS
        fields = ['phone', 'state']
        widgets = {
            'phone': Select(choices=phoneSMS.objects.all().values_list('id', 'phone'), attrs={'class':'form-control',}),
            'state': bootStrapButtonSelect( attrs={'class': 'buttons-sms', }), }

What I want to do is to filter that phoneSMS with only the phones which contains the sms reference. Here're the models:

class SMS(models.Model):
    student = models.ForeignKey(Student)
    day = models.DateField(db_index=True)
    tries = models.IntegerField(default=0)
    phone = models.CharField(max_length=9, default='---')
    sent = models.BooleanField(default=False)
    state = models.CharField(max_length=20, choices=OPTIONS, default='nothing')



class phoneSMS(models.Model):
    phone= models.CharField(max_length=120)
    sms = models.ForeignKey(SMS)

I tried with objects.filter(sms=SMS) but no result.

Était-ce utile?

La solution

In the moment of declaration you have no information about model instance ModelForm will be initialized with.

You have to dynamically set choices when model instance is already known and it happens not earlier than in __init__() method:

class SmsForm(ModelForm):

    class Meta:
        model = SMS
        fields = ['phone', 'state']
        widgets = {
            'phone': Select(attrs={'class':'form-control',}),
            'state': bootStrapButtonSelect( attrs={'class': 'buttons-sms', })
        }

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

        self.fields['phone'].widget.choices = \
             phoneSMS.objects.filter(sms=self.instance.sms) \
                             .values_list('id', 'phone')

Still be careful as nobody guaranties that self.instance is set - it depends on optional instance argument. So better attach proper conditions and way of handling such case.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top