0

I want to filter the options that appear in a M2M field of a form using a queryset. I have read that limit_choices_to can only be used with ForeignKey. Is there something similar to limit_choices_to that can be applied to M2M?

This is my model:

class Inspection(models.Model):

    ref         = models.CharField(max_length=50)
    tools       = models.CharField(max_length=150,null=True,blank=True)
    areas       = models.ManyToManyField('specimens.Area',null=True,blank=True)

And this is the model of the M2M field:

class Area(models.Model):

    ref         = models.CharField(max_length=10)
    description = models.TextField(max_length=150)
    specimen    = models.ForeignKey(Specimen)

    class Meta:
        unique_together = ['ref','specimen']

I would want to filter inspection_areas with a queryset: Area.objects.filter(specimen="specimen")

Other post (Many to many and how to get a queryset from queryset) explains a way to do this, changing the admin form I think (I don't understand it so much), but this does not work for me, getting DoesNotExist errors or Super errors. Do I have to change my InspectionForm for the InspectionAdminForm that says the post before?

enter image description here

Any ideas?

EDIT-1:

I have realized that it throws other different error:

enter image description here

This is the complete code I have used:

class InspectionAdminForm(forms.ModelForm):

    class Meta:
        model = Inspection

    def __init__(self, *args, **kwargs):
        super(InspectionAdminForm,self).__init__(*args,**kwargs)
        self.fields['areas'].queryset = Area.objects.filter(specimen=self.instance.specimen)



class InspectionAdmin(admin.ModelAdmin):
    form = InspectionAdminForm
    filter_horizontal = ['areas']
Community
  • 1
  • 1
DavidRguez
  • 1,070
  • 3
  • 12
  • 27
  • Did you perform `makemigrations` and `migrate` after setting up your models? It looks like it does not know where to put your data (nor fetch it from)... – mccc Oct 30 '14 at 08:49
  • You're right. I forgot to migrate. Solved the latest error. I don't have any errors now, but the queryset filter only works in my Admin view, while in my form I still view all the Area options without filtering. – DavidRguez Oct 30 '14 at 08:55

1 Answers1

0

As I had set some initial parameters to my Inspection modelForm, I set:

inspectionform = InspectionForm(None, initial={'specimen':specimen})

I also change the __init__ method of the InspectionForm:

class InspectionForm(forms.ModelForm):

    class Meta:
        model = Inspection

    def __init__(self, *args, **kwargs):
        super(InspectionForm,self).__init__(*args,**kwargs)
        self.fields['areas'].queryset = Area.objects.filter(specimen=kwargs['initial']['specimen'].id)

And that's all! Now it works great.

DavidRguez
  • 1,070
  • 3
  • 12
  • 27