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?
Any ideas?
EDIT-1:
I have realized that it throws other different error:
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']
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.