Introduction to admin file in django
In this tutorial we will learn about the admin.py file in django and it's related operation.
#main urls.py
admin.site.site_title=""
admin.site.site_header=""
To render a model in Django admin, we need to modify myapp/admin.py
from django.contrib import admin
from django.contrib.admin import DateFieldListFilter
# Register your models here.
from myapp.models import ConfigCategory,ConfigChoice
admin.site.register(Blog)
class ChoiceInline(admin.StackedInline):
model = ConfigChoice
extra = 0
@admin.register(ConfigCategory)
class ConfigCategoryAdmin(admin.ModelAdmin):
add_form = CustomUserAddForm
form = CustomUserChangeForm
list_display = ["uuid", "name","full_name", "system", "description", "created_at""updated_at","color_name"]
list_editable=['status']
list_filter = ["created_at","system__name, ("created_at", DateFieldListFilter)]
empty_value_display = 'Not Available'
search_fields = ["name","system__name"]
fields = ('name', 'begin_datetime') #if you want to show only few field in admin
exclude = ('end_datetime', )
inlines = [ChoiceInline]
readonly_fields = ('created_at', 'updated_at', 'created_by')
ordering = ('id', )
prepopulated_fields={"slug":("name","address")}
list_display_links=['id','title']
save_on_top=True
list_per_page=10
radio_fields={"choices_field_in_model":admin.HORIZONTAL}
def color_name(self,obj):
return format_html(f'<span style="color:red">{obj.name}<span>')
def clickme(self,obj):
return format_html(f'<a href="/admin/ajax/student/{obj.id}/change/"> View </a>')
def photo_tage(self,obj):
return format_html(f'<img src="/media/{obj.profile}" style="height:50px;width:50px"/>')
readonly_fields=["photo_tage"] # to show any user define field in detail page , mention here
"""
The raw_id_fields Input widget should contain a primary key if the field is a ForeignKey or a
comma separated list of values if the field is a ManyToManyField.
"""
raw_id_fields = ("show",)
date_hierarchy = "begin_datetime"
#to show less content
def less_content(self,obj):
return obj.description[:30]
#now you can mention less_content in list-display
#you can defile custom field also too
def full_name(self, obj):
return f"{obj.name} {obj.last_name}"
#fieldsets control the layout of admin
fieldsets = (
("Some options", {
'fields': ('name', 'show')
}),
('Date options', {
'classes': ('collapse',),
'fields': ('begin_datetime', 'end_datetime'),
}),
)
fieldsets = (
('User', {'fields': ('uuid', 'username', 'email', 'password', 'created_by')}),
('Permissions', {'fields': ('is_active', 'is_superuser', 'is_admin', 'is_staff')}),
('Dates', {'fields': ('created_at', 'updated_at', 'last_login',)}),
)
add_fieldsets = (
(None, {
"classes": ("wide",),
"fields": ("email", "username", "password", "confirm_password"),
}),
)
#to provide permission
MAX_OBJECTS=10
def has_add_permission(self, request):
if self.model.objects.count() >= MAX_OBJECTS:
return False
return super().has_add_permission(request)
Django Admin Interface can be used to graphically implement CRUD (Create, Retrieve, Update, Delete).
Custom Django admin List action
Django Admin List actions are used to perform operations in bulk.
Example Model
from django.db import models
class Ticket(models.Model):
STATUS = (
('P', 'In Process'),
('S', 'Success'),
('C', 'Cancled'),
)
name = models.CharField(max_length=225)
status = models.CharField(choices=STATUS,
max_length=20,
help_text="Status of this instance")
admin.py
from django.contrib import admin
from app.models import Ticket, Show
@admin.register(Ticket)
class TickerAdmin(admin.ModelAdmin):
list_display = ('id', 'status', 'show', 'begin_datetime', 'end_datetime')
actions = ["cancel_tickets"]
def cancel_tickets(self, request, queryset):
for ticket in queryset:
ticket.status = "C"
ticket.save()
cancel_tickets.short_description = 'Cancel Selected Tickets'
Django save_model method()
Django Admin save_model is used to create and update model object from Django admin panel
from django.contrib import admin
from app.models import Ticket
@admin.register(Ticket)
class TickerAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if not change:
obj.owner = request.user
elif change:
obj.updated_by = request.user
super().save_model(request, obj, form, change)
How to show Image field in django admin panel
There are two possible approach to do that
1. Using mark_safe()
2. Using sorl-thumbnail()
1. Using mark_safe()
model.py
from django.db import models
from django.utils.html import mark_safe
class Post(models.Model):
title = models.CharField(max_length=255)
thumbnail = models.ImageField(upload_to='post/thumbnail/%Y/%m/%d/', null=True, blank=True)
@property
def thumbnail_preview(self):
if self.thumbnail:
return mark_safe('<img src="{}" width="300" height="300" />'.format(self.thumbnail.url))
return ""
admin.py
from django.contrib import admin
from post.models import Post
class PostAdmin(admin.ModelAdmin):
list_display = ('id', 'title')
readonly_fields = ('thumbnail_preview',)
def thumbnail_preview(self, obj):
return obj.thumbnail_preview
thumbnail_preview.short_description = 'Thumbnail Preview'
thumbnail_preview.allow_tags = True
admin.site.register(Post, PostAdmin)
2. Using sorl-thumbnail()
First we need to install sorl-thumbnail
$ pip install sorl-thumbnail
Then register sorl.thumbnail, in the INSTALLED_APPS section of your project's settings.
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.admin',
'django.contrib.sites',
'django.contrib.comments',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.contenttypes',
'sorl.thumbnail',
]
Now run migrate command
python manage.py migrate
models.py
from django.db import models
from sorl.thumbnail import get_thumbnail
from django.utils.html import format_html
class Post(models.Model):
title = models.CharField(max_length=255)
thumbnail = models.ImageField(upload_to='post/thumbnail/%Y/%m/%d/', null=True, blank=True)
@property
def thumbnail_preview(self):
if self.thumbnail:
_thumbnail = get_thumbnail(self.thumbnail,
'300x300',
upscale=False,
crop=False,
quality=100)
return format_html('<img src="{}" width="{}" height="{}">'.format(_thumbnail.url, _thumbnail.width, _thumbnail.height))
return ""
admin.py
from django.contrib import admin
from post.models import Post
class PostAdmin(admin.ModelAdmin):
list_display = ('id', 'title')
readonly_fields = ('thumbnail_preview',)
def thumbnail_preview(self, obj):
return obj.thumbnail_preview
thumbnail_preview.short_description = 'Thumbnail Preview'
thumbnail_preview.allow_tags = True
admin.site.register(Post, PostAdmin)
You can also show thumbnail preview in admin List by adding thumbnail_preview in list_display
list_display = ('id', 'title', 'thumbnail_preview')
Login with email instead of username in django admin
models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
USERNAME_FIELD = 'email'
email = models.EmailField(max_length=255, unique=True)
REQUIRED_FIELDS = [] # removes email from REQUIRED_FIELDS
Don’t forget to point AUTH_USER_MODEL to it.
settings.py
AUTH_USER_MODEL = ‘your_app.User’
Now register the model in the app’s admin.py:
admin.py
from django.contrib.auth.admin import UserAdmin
admin.site.register(User, UserAdmin)
How to apply filter on foreignkey in Django admin panel
In order to apply a filter on Foreign Key in Django admin, we need to override formfield_for_foreignkey method admin.py file.
admin.py
class PostAdmin(admin.ModelAdmin):
list_display = ('id', 'title')
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "author":
kwargs["queryset"] = User.objects.filter(is_author=True)
return super(PostAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
How to apply filter on manytomany key in Django admin panel
Suppose we have to model User and Post.
models.py
from django.db import models
class User(models.Model):
name = models.CharField(max_length=255)
is_author = models.BooleanField(default=False)
class Post(models.Model):
title = models.CharField(max_length=255)
author = models.ManyToManyField(User, related_name="posts", blank=True)
Now in Post.author we want to show only those uses whose is_author is True.
admin.py
from django.contrib import admin
from post.models import Post, User
class PostAdmin(admin.ModelAdmin):
list_display = ('id', 'title')
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == "author":
kwargs["queryset"] = User.objects.filter(is_author=True)
return super(PostAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
class UserAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'is_author')
admin.site.register(Post, PostAdmin)
admin.site.register(User, UserAdmin)
some of the admin panel setup
1.django-jazzmin
https://django-jazzmin.readthedocs.io/
https://djangocentral.com/making-django-admin-jazzy-with-django-jazzmin/
https://pypi.org/project/django-jazzmin/
2.django-material-admin
https://pypi.org/project/django-material-admin/
3.django jet3
pip install django-3-jet
https://pypi.org/project/django-3-jet/
https://jet.readthedocs.io/en/latest/
4.How to integrate Adminlte in django
You can visite the site https://adminlte.io/ and go through downlaod section and download source code in zip formate.
then you have to setup all the satic file and template setting.
other important links:
https://adminlte.io/themes/v3/#