Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enabling Django Admin Filters on Many-to-Many Fields

I have a simple Django model resembling:

class Address(models.Model):
    blah

class MemberData(models.Model):
    user = models.ForeignKey(User)
    addresses = models.ManyToManyField(Address)

I want to expose the Address model in admin to allow a user to filter Address records by their associated user. e.g.

class AddressAdmin(admin.ModelAdmin):
    model = Address
    list_filter = [???]

The ModelAdmin.list_filter property allows this, but I'm not sure what field name to use to support my many-to-many relationship. If the Address model has a direct reference to the MemberData model, I could do something like:

class AddressAdmin(admin.ModelAdmin):
    model = Address
    list_filter = ['memberdata__user']

Is there any equivalent syntax for an indirect many-to-many relationship? If not, is there any workaround to accomplish the same end?

like image 275
Cerin Avatar asked Mar 18 '11 21:03

Cerin


People also ask

How fetch data from many to many field in Django?

A ManyToManyField in Django is a field that allows multiple objects to be stored. This is useful and applicable for things such as shopping carts, where a user can buy multiple products. To add an item to a ManyToManyField, we can use the add() function.

What is many to many field Django?

A ManyToMany field is used when a model needs to reference multiple instances of another model. Use cases include: A user needs to assign multiple categories to a blog post. A user wants to add multiple blog posts to a publication.

What is list filter in Django?

For Django 1.4-1.7, list_filter allows you to use a subclass of SimpleListFilter . It should be possible to create a simple list filter that lists the values you want. If you can't upgrade from Django 1.3, you'd need to use the internal, and undocumented, FilterSpec api.


2 Answers

I believe in a case like this, you could make a trivial through model for your M2M relation, and then use the normal syntax to follow the (now explicit) ForeignKeys. Something like:

class Address(models.Model):
    blah

class MemberData(models.Model):
    user = models.ForeignKey(User)
    addresses = models.ManyToManyField(Address,through='MemberAddress')

class MemberAddress(models.Model):
    member = models.ForeignKey(MemberData)
    address = models.ForeignKey(Address)

and in the admin:

class AddressAdmin(admin.ModelAdmin):
    model = Address
    list_filter = ['memberaddress_set__member__user']
like image 111
Michael C. O'Connor Avatar answered Oct 11 '22 23:10

Michael C. O'Connor


I'm using 1.5 and list_filter = ['memberdata__user'] seems like it would work.

like image 25
Aaron McMillin Avatar answered Oct 11 '22 21:10

Aaron McMillin