Filtering Django Admin by Null/Is Not Null

后端 未结 7 1419
太阳男子
太阳男子 2020-12-16 15:03

I have a simple Django model like:

class Person(models.Model):
    referrer = models.ForeignKey(\'self\', null=True)
    ...

In this model\

相关标签:
7条回答
  • 2020-12-16 16:07

    I ended up using a mixture of the top solution here, along with this snippet.

    However, I had to tweak the snippet slightly, dropping the field type restriction and adding the new field_path, recently added in 1.3.

    from django.contrib.admin.filterspecs import FilterSpec
    from django.db import models
    from django.utils.safestring import mark_safe
    from django.utils.translation import ugettext as _
    
    class NullFilterSpec(FilterSpec):
        #fields = (models.CharField, models.IntegerField, models.FileField)
    
        @classmethod
        def test(cls, field):
            #return field.null and isinstance(field, cls.fields) and not field._choices
            return field.null and not field._choices
        #test = classmethod(test)
    
        def __init__(self, f, request, params, model, model_admin, field_path=None):
            super(NullFilterSpec, self).__init__(f, request, params, model, model_admin, field_path)
            self.lookup_kwarg = '%s__isnull' % f.name
            self.lookup_val = request.GET.get(self.lookup_kwarg, None)
    
        def choices(self, cl):
            # bool(v) must be False for IS NOT NULL and True for IS NULL, but can only be a string
            for k, v in ((_('All'), None), (_('Has value'), ''), (_('Omitted'), '1')):
                yield {
                    'selected' : self.lookup_val == v,
                    'query_string' : cl.get_query_string({self.lookup_kwarg : v}),
                    'display' : k
                }
    
    # Here, we insert the new FilterSpec at the first position, to be sure
    # it gets picked up before any other
    FilterSpec.filter_specs.insert(0,
        # If the field has a `profilecountry_filter` attribute set to True
        # the this FilterSpec will be used
        (lambda f: getattr(f, 'isnull_filter', False), NullFilterSpec)
    )
    
    0 讨论(0)
提交回复
热议问题