Can I make list_filter in django admin to only show referenced ForeignKeys?

前端 未结 7 1698
灰色年华
灰色年华 2020-12-02 07:02

I have a django application which has two models like this:

class MyModel(models.Model):
    name = models.CharField()
    country = models.ForeignKey(\'Coun         


        
7条回答
  •  眼角桃花
    2020-12-02 07:38

    This is my take on a general and reusable implementation for Django 1.4, if you happen to be stuck at that version. It is inspired by the built-in version that is now part of Django 1.8 and upwards. Also, it should be quite a small task to adapt it to 1.5–1.7, mainly the queryset methods have changed name in those. I've put the filter itself in a core application that I have but you can obviously put it anywhere.

    Implementation:

    # myproject/core/admin/filters.py:
    
    from django.contrib.admin.filters import RelatedFieldListFilter
    
    
    class RelatedOnlyFieldListFilter(RelatedFieldListFilter):
        def __init__(self, field, request, params, model, model_admin, field_path):
            self.request = request
            self.model_admin = model_admin
            super(RelatedOnlyFieldListFilter, self).__init__(field, request, params, model, model_admin, field_path)
    
        def choices(self, cl):
            limit_choices_to = set(self.model_admin.queryset(self.request).values_list(self.field.name, flat=True))
            self.lookup_choices = [(pk_val, val) for pk_val, val in self.lookup_choices if pk_val in limit_choices_to]
            return super(RelatedOnlyFieldListFilter, self).choices(cl)
    

    Usage:

    # myapp/admin.py:
    
    from django.contrib import admin
    from myproject.core.admin.filters import RelatedOnlyFieldListFilter
    from myproject.myapp.models import MyClass
    
    
    class MyClassAdmin(admin.ModelAdmin):
        list_filter = (
            ('myfield', RelatedOnlyFieldListFilter),
        )
    
    admin.site.register(MyClass, MyClassAdmin)
    

    If you later update to Django 1.8 you should be able to just change this import:

    from myproject.core.admin.filters import RelatedOnlyFieldListFilter
    

    To this:

    from django.contrib.admin.filters import RelatedOnlyFieldListFilter
    

提交回复
热议问题