Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django admin filters on remote field via get_list_filter

I have 3 models, linked by FKs in a chain like this:

class Customer(models.Model):
    name = models.CharField(max_length=100)


class Order(models.Model):
    name = models.CharField(max_length=100)
    customer = models.ForeignKey(
        'customer.Customer', on_delete=models.PROTECT)


class Task(models.Model):
    name = models.CharField(max_length=100)
    order = models.ForeignKey(
        'order.Order', on_delete=models.PROTECT)

Now, if within my TaskAdmin, I use:

list_filter = ('order__customer', )

everything works fine. But if I go with:

def get_list_filter(self, request):
    return ('order__customer', )

the page loads, but as soon as I click on any possibile customer, a Bad Request (400) error page appears. It sounds like a Django bug to me, but maybe I'm doing something wrong here... any hints?

like image 574
Seether Avatar asked Oct 22 '25 13:10

Seether


1 Answers

I don't have enough reputation to add a comment, so I'll write here, even if this is not a real answer.

It looks there's an open ticket on this topic: lookup_allowed fails to consider dynamic list_filter

You can use two different workarounds to quickly solve this problem until it will be fixed upstream:

  • in addition to get_list_filter you can define list_filter = ('order__customer',), so that this field's lookups will always be whitelisted, even if not used (because get_list_filter has precedence)
  • you can override lookup_allowed this way:

    def lookup_allowed(self, lookup, *args, **kwargs):
        if lookup == 'order__customer__id__exact':
            return True
        return super(TaskAdmin, self).lookup_allowed(lookup, *args, **kwargs)
    

    this explicitly allows the single lookup that will be used as url param.

like image 193
Bug Spencer Avatar answered Oct 27 '25 02:10

Bug Spencer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!