Skip to content

Commit

Permalink
Added chapter on filtering on calculated fields
Browse files Browse the repository at this point in the history
  • Loading branch information
shabda committed Feb 6, 2018
1 parent 3b4c9b9 commit d93e7f0
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 1 deletion.
Binary file added docs/filter_calculated_fixed.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions docs/filtering_calculated_fields.rst
Original file line number Diff line number Diff line change
@@ -1,2 +1,45 @@
How to enable filtering on calculated fields?
===========================================================


You have a :code:`Hero` admin which looks like this::

@admin.register(Hero)
class HeroAdmin(admin.ModelAdmin):
list_display = ("name", "is_immortal", "category", "origin", "is_very_benevolent")
list_filter = ("is_immortal", "category", "origin",)

def is_very_benevolent(self, obj):
return obj.benevolence_factor > 75

It has one calculated field :code:`is_very_benevolent`, and your admin looks like this

.. image:: no_filtering.png

You have added filtering on the fields which come from the models, but you also want to add filtering on the calculated field. To do this, you will need to subclass
:code:`SimpleListFilter` like this::


class IsVeryBenevolentFilter(admin.SimpleListFilter):
title = 'is_very_benevolent'
parameter_name = 'is_very_benevolent'

def lookups(self, request, model_admin):
return (
('Yes', 'Yes'),
('No', 'No'),
)

def queryset(self, request, queryset):
value = self.value()
if value == 'Yes':
return queryset.filter(benevolence_factor__gt=75)
elif value == 'No':
return queryset.exclude(benevolence_factor__gt=75)
return queryset

And then change your :code:`list_filter` to :code:`list_filter = ("is_immortal", "category", "origin", IsVeryBenevolentFilter)`.

With this you can filter on the calcualted field, and your admin looks like this:

.. image:: filter_calculated_fixed.png
Binary file added docs/no_filtering.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 24 additions & 1 deletion heroes_and_monsters/entities/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,32 @@
admin.site.register(Villain)


class IsVeryBenevolentFilter(admin.SimpleListFilter):
title = 'is_very_benevolent'
parameter_name = 'is_very_benevolent'

def lookups(self, request, model_admin):
return (
('Yes', 'Yes'),
('No', 'No'),
)

def queryset(self, request, queryset):
value = self.value()
if value == 'Yes':
return queryset.filter(benevolence_factor__gt=75)
elif value == 'No':
return queryset.exclude(benevolence_factor__gt=75)
return queryset


@admin.register(Hero)
class HeroAdmin(admin.ModelAdmin):
list_display = ("name", "gender", "is_immortal", "category", "origin")
list_display = ("name", "is_immortal", "category", "origin", "is_very_benevolent")
list_filter = ("is_immortal", "category", "origin", IsVeryBenevolentFilter)

def is_very_benevolent(self, obj):
return obj.benevolence_factor > 75


@admin.register(Category)
Expand Down

0 comments on commit d93e7f0

Please sign in to comment.