Skip to content

Commit

Permalink
Added clauclted fields chapter
Browse files Browse the repository at this point in the history
  • Loading branch information
shabda committed Feb 6, 2018
1 parent 48bc81c commit dcc2335
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 8 deletions.
Binary file added docs/calculated_field.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 53 additions & 0 deletions docs/calculated_fields.rst
Original file line number Diff line number Diff line change
@@ -1,2 +1,55 @@
How to show calculated fields on listview page?
===========================================================

You have an admin for the :code:`Origin` model like this::

@admin.register(Origin)
class OriginAdmin(admin.ModelAdmin):
list_display = ("name",)


Apart from the name, we also want to show the number of heroes and number of villains for each origin, which is not a DB field on :code:`Origin`.
You can do this in two ways.


Adding a method to the model
===========================================================

You can add two methods to your :code:`Origin` model like this::


def hero_count(self,):
return self.hero_set.count()

def villain_count(self):
return self.villain_set.count()

And change :code"`list_display` to :code:`list_display = ("name", "hero_count", "villain_count")`.


Adding a method to the ModelAdmin
===========================================================

If you don't want to add method to the model, you can do instead add the method to the ModelAdmin. ::



def hero_count(self, obj):
return obj.hero_set.count()

def villain_count(self, obj):
return obj.villain_set.count()


The :code:`list_display`, as earlier, changes to :code:`list_display = ("name", "hero_count", "villain_count")`.

Performance considerations for calculated_fields
===========================================================

With either of the above approaches, you would be running two exta queries per object (One per caluclated field). You can find how to optimize this in
:doc:`optimize_queries`.


With any of these changes your admin looks like this:

.. image:: calculated_field.png
8 changes: 4 additions & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.1'
# The full version, including alpha/beta/rc tags.
release = '0.1'
# This will track teh Django version against whihch this is written.
version = '2.0'

release = '2.0'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
1 change: 0 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ Text and Design
remove_default
logo
override_default_templates
set_ordering

Calculated fields
+++++++++++++++++++++
Expand Down
25 changes: 22 additions & 3 deletions heroes_and_monsters/entities/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,26 @@

from .models import Hero, Villain, Category, Origin

admin.site.register(Hero)
admin.site.register(Villain)
admin.site.register(Category)
admin.site.register(Origin)


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


@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ("name",)


@admin.register(Origin)
class OriginAdmin(admin.ModelAdmin):
list_display = ("name", "hero_count", "villain_count")


def hero_count(self, obj):
return obj.hero_set.count()

def villain_count(self, obj):
return obj.villain_set.count()

0 comments on commit dcc2335

Please sign in to comment.