Django Admin Cookbook, Quizzes of Computer science

Django Admin Cookbook a book of a cookbook

Typology: Quizzes

2022/2023

Uploaded on 06/03/2024

909808-90098008
909808-90098008 🇺🇿

1 / 49

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Django Admin Cookbook
Release 2.0
Agiliq
May 22, 2018
Contents
1 Django Admin Cookbook - How to do things with Django admin. 1
2 Text and Design 2
3 Calculated fields 10
4 Bulk and custom actions 17
5 Permissions 24
6 Multiple models and inlines 27
7 Listview Page 31
8 Changeview Page 34
9 Misc 41
10 Indices and tables 46
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31

Partial preview of the text

Download Django Admin Cookbook and more Quizzes Computer science in PDF only on Docsity!

Django Admin Cookbook

  • Release 2.
    • May 22, Agiliq
  • 1 Django Admin Cookbook - How to do things with Django admin. Contents
  • 2 Text and Design
  • 3 Calculated fields
  • 4 Bulk and custom actions
  • 5 Permissions
  • 6 Multiple models and inlines
  • 7 Listview Page
  • 8 Changeview Page
  • 9 Misc
  • 10 Indices and tables

1 Django Admin Cookbook - How to do things with Django admin.

This is a book about doing things with Django admin. It takes the form of about forty questions and common tasks

with Django admin we answer.

The chapters are based on a common set of models, which you can read in detail here (Models used in this book). In

short, we have two apps, events and entities. The models are

  • Events: Epic, Event, EventHero, EventVillian
  • Entities: Category, Origin, Hero, Villain

1.1 Introduction

Django Admin Cookbook is a book about doing things with Django admin. It is targeted towards intermediate Django

developers, who have some experience with Django admin, but are looking to expand their knowledge of Django

admin and achieve mastery of Django admin.

It takes the form of question and answers about common tasks you might do with Django admin. All the chapters are

based on a common set of models, which you can read in detail here (Models used in this book). In short, we have two

apps, events and entities. The models are

  • Events: Epic, Event, EventHero, EventVillain
  • Entities: Category, Origin, Hero, Villain

site_header can be set to change this.

Listview Page

BY default it looks like this and is set to “Site administration”

index_title can be set to change this.

HTML title tag

By default it looks like this and is set to “Django site admin”

site_title can be set to change this.

We can make the three changes in urls.py:

2.3 How to create two independent admin sites?

The usual way to create admin pages is to put all models in a single admin. However it is possible to have multiple

admin sites in a single Django app.

Right now our entity and event models are in same place. UMSRA has two distinct group researching Events

and Entities, and so wants to split the admins.

We will keep the default admin for entities and create a new subclass of AdminSite for events.

In our events/admin.py we do:

from django.contrib.admin import AdminSite class EventAdminSite (AdminSite): site_header = "UMSRA Events Admin" site_title = "UMSRA Events Admin Portal" index_title = "Welcome to UMSRA Researcher Events Portal"

event_admin_site = EventAdminSite(name='event_admin')

event_admin_site.register(Epic) event_admin_site.register(Event) event_admin_site.register(EventHero) event_admin_site.register(EventVillain)

And change the urls.py to

from events.admin import event_admin_site

(continues on next page)

(continued from previous page)

urlpatterns = [ path('entity-admin/', admin.site.urls), path('event-admin/', event_admin_site.urls), ]

This separates the admin. Both admins are available at their respective urls, /entity-admin/ and

event-admin/.

2.4 How to remove default apps from Django admin?

Django will include django.contrib.auth in INSTALLED_APPS, which means User and Groups models are

included in admin automatically.

If you want to remove it, you will have to unregister them.

from django.contrib.auth.models import User, Group

admin.site.unregister(User) admin.site.unregister(Group)

After making these changes, your admin should look like this.

(continued from previous page)

With the changes your base_site.html will look like this:

{% extends "admin/base.html" %}

{% load staticfiles %}

{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% ˓→endblock %}

{% block branding %}

{% endblock %}

{% block nav- global %}{% endblock %}

And your admin will look like this

2.6 How to override Django admin templates?

https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-admin-templates

3 Calculated fields

3.1 How to show calculated fields on listview page?

You have an admin for the 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 Origin. You can do this in two ways.

Adding a method to the model

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

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

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

And change list_display to 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 list_display, as earlier, changes to 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 calculated field). You

can find how to optimize this in How to optimize queries in Django admin?.

With any of these changes your admin looks like this:

(continued from previous page) def hero_count(self, obj): return obj._hero_count

def villain_count(self, obj): return obj._villain_count

There are no per object extra queries. Your admin continues to look like it did before the annotate call.

3.3 How to enable sorting on calculated fields?

Django adds sorting capabilities on fields which are attributes on the models. When you add a calculated field Django

doesn’t know how to do a order_by, so it doesn’t add sorting capability on that field.

If you want to add sorting on a calculated field, you have to tell Django what to pass to order_by. You can do this

by setting the admin_order_field attribute on the calculated field method.

You start from the admin you wrote in the previous chapter (How to optimize queries in Django admin?).:

hero_count.admin_order_field = '_hero_count' villain_count.admin_order_field = '_villain_count'

With these changes your admin becomes:

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

def get_queryset(self, request): queryset = super().get_queryset(request) queryset = queryset.annotate( _hero_count=Count("hero", distinct= True ), _villain_count=Count("villain", distinct= True ), ) return queryset (continues on next page)

(continued from previous page)

def hero_count(self, obj): return obj._hero_count

def villain_count(self, obj): return obj._villain_count

hero_count.admin_order_field = '_hero_count' villain_count.admin_order_field = '_villain_count'

Here is the admin sorted on hero_count

3.4 How to enable filtering on calculated fields?

You have a 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 is_very_benevolent, and your admin looks like this

3.5 How to show “on” or “off” icons for calculated boolean fields?

In the previous chapter, How to enable filtering on calculated fields? you added a boolean field.:

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

Which looks like this

The is_very_benevolent field shows the string True and False, unlike the builtin BooleanFields which show an

on and off indicator. To fix this, you add a boolean attribute on your method. You final modeladmin 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", IsVeryBenevolentFilter)

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

is_very_benevolent.boolean = True

And your admin looks like this

(continued from previous page)

export_as_csv.short_description = "Export Selected"

This adds an action called export selected, which looks like this:

You will then change the export_as_csv to this:

import csv from django.http import HttpResponse ...

def export_as_csv(self, request, queryset):

meta = self.model._meta field_names = [field.name for field in meta.fields]

response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta) writer = csv.writer(response)

writer.writerow(field_names) for obj in queryset: row = writer.writerow([getattr(obj, field) for field in field_names])

return response

This exports all of the selected rows. If you notice, export_as_csv doens’t have anything specific to Hero, so

you can extract the method to a mixin.

With the changes, your code looks like this:

class ExportCsvMixin : def export_as_csv(self, request, queryset):

meta = self.model._meta field_names = [field.name for field in meta.fields]

response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta) writer = csv.writer(response)

writer.writerow(field_names) for obj in queryset: row = writer.writerow([getattr(obj, field) for field in field_names])

return response

export_as_csv.short_description = "Export Selected"

@admin .register(Hero) class HeroAdmin (admin.ModelAdmin, ExportCsvMixin): list_display = ("name", "is_immortal", "category", "origin", "is_very_benevolent") list_filter = ("is_immortal", "category", "origin", IsVeryBenevolentFilter) actions = ["export_as_csv"]

...

@admin .register(Villain) class VillainAdmin (admin.ModelAdmin, ExportCsvMixin): list_display = ("name", "category", "origin") actions = ["export_as_csv"]

You can add such an export to other models by subclassing from ExportCsvMixin

4.3 How to remove the delete selected action in Django admin?

By default Django adds a Delete Selected action to the listview page. You have been asked to remove the action from

the Hero admin.

The method ModelAdmin.get_actions returns the actions shown. By overriding this method, to remove

delete_selected We can remove it form the dropdown. Your code looks like this with the changes.:

def get_actions(self, request): actions = super().get_actions(request) if 'delete_selected' in actions: del actions['delete_selected'] return actions

And your admin looks like this