Skip to content

Instantly share code, notes, and snippets.

@majackson
Created November 2, 2015 11:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save majackson/41fc9c9e725c7f432ee5 to your computer and use it in GitHub Desktop.
Save majackson/41fc9c9e725c7f432ee5 to your computer and use it in GitHub Desktop.
A reusable list filter for displaying/filtering ArrayFields in the django admin
from django.contrib import admin
class ArrayFieldListFilter(admin.SimpleListFilter):
"Admin-filterable field for an ArrayList"
def __init__(self, request, params, model, model_admin):
self._choices = model._meta.get_field(self.parameter_name).base_field.choices
super(ArrayFieldListFilter, self).__init__(request, params, model, model_admin)
def lookups(self, request, model_admin):
""""Returns a list of tuples:
(lookup value, human-readable value)
for use in admins right sidebar
"""
return self._choices
def queryset(self, request, queryset):
"Filter based on clicked value stored in self.value()"
value = self.value()
if value:
queryset = queryset.filter(**{
'{}__contains'.format(self.parameter_name): [value]
})
return queryset
def get_arrayfield_list_filter(field_name):
class ArrayFieldListFilterForField(ArrayFieldListFilter):
parameter_name = field_name
title = field_name.title()
return ArrayFieldListFilterForField
@nskalis
Copy link

nskalis commented Mar 19, 2018

Thanks a lot for this gist!

Could you please advise on how to resolve the error ? It happens when I click on any of the filtering options.

Request Method: | GET
-- | --
http://registry.ip-spotlight.aorta.net/admin/bgp/communities/?labels=bgp-customer
2.0.2
ProgrammingError
operator does not exist: text[] @> character varying[] LINE 1: ..." FROM "communities" WHERE "communities"."labels" @> ARRAY['...                                                              ^ HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
/usr/lib/python3.4/site-packages/django/db/backends/utils.py in _execute, line 85
/usr/bin/python3
3.4.5

my admin.py looks like this:

class ArrayFieldListFilter(admin.SimpleListFilter):

    def __init__(self, request, params, model, model_admin):
        self._choices = model._meta.get_field(self.parameter_name).base_field.choices
        super(ArrayFieldListFilter, self).__init__(request, params, model, model_admin)

    def lookups(self, request, model_admin):
        return self._choices

    def queryset(self, request, queryset):
        value = self.value()
        if value:
            queryset = queryset.filter(**{
                '{}__contains'.format(self.parameter_name): [value]
            })
        return queryset


def get_arrayfield_list_filter(field_name):

    class ArrayFieldListFilterForField(ArrayFieldListFilter):
        parameter_name = field_name
        title = field_name.title()

    return ArrayFieldListFilterForField



class CommunitiesAdmin(admin.ModelAdmin):

    list_display    = ("name", "value", "description", "show_labels", "updated_on")
    search_fields   = ("name", "value", "description")
    list_filter     = (get_arrayfield_list_filter("labels"), "updated_on")
    # actions         = [ export_as_csv_action(fields=["name", "value", "description", "labels"], exclude=["updated_on"]) ]

    def show_labels(self, obj):
        return str(";".join(obj.labels))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment