django contrib admin
Django comes with a built-in admin interface.
Touring the Django Admin
As the name implies, the Django Admin’s purpose is administering your website. Its interface isn’t the prettiest, and its design is focused on users who control your site. Before using the Admin, you need to understand the basics of user permissions. Django is a multi-user framework, meaning you can create websites that have user accounts, and each account can be restricted to a subset of activities. Django has fine-grained permission control, and you can get quite specific about who can do what, but it also has a high-level mechanism that is good enough for most situations.
Note
Django divides users into three classes:
- General User
- Staff
- Admin
Django in Action MEAP V01
Django Manager
Django Manager
In Django, a Manager is a class that provides methods for querying the database and performing CRUD
(Create
, Read
, Update
, Delete
) operations on model instances. Every Django model has at least one Manager, and the default Manager is named objects.
The objects Manager provides several methods to interact with the database. Here are some commonly used methods:
- YourModel.objects.all()
- YourModel.objects.get(id=1)
- YourModel.objects.filter(field=value)
- YourModel.objects.exclude(field=value)
- YourModel.objects.order_by('-field')
- YourModel.objects.first()
- YourModel.objects.last()
- YourModel.objects.values('field1', 'field2')
In the context of databases
or models
, entities typically refer to the objects or items that are represented and stored within the database. In a database management system, entities are often mapped to tables, and each row in the table represents a specific instance of that entity.
In the context of Django's models
, entities usually refer to the objects that you define using Django's Object-Relational Mapping (ORM). In Django, you define entities using model classes, which represent tables in the database. Each instance of a model class corresponds to a row in the respective table, and each attribute of the model class typically corresponds to a column in the table.
For example, consider a simple Django model representing a user:
from django.db import models
class User(models.Model):
username = models.CharField(max_length=100)
email = models.EmailField()
In this example, User is the entity, and it's represented by the model class User. The attributes username and email define the properties of this entity, which will be stored as columns in the database table representing the User entity.
Entities play a crucial role in database design and modeling as they represent real-world objects or concepts within the system being developed. They help in organizing and structuring data in a way that reflects the relationships and behaviors of the system's components.
Rename model name in django admin
Example
To rename the model name in the Django admin interface, you can use the verbose_name and verbose_name_plural attributes in the model's Meta class. Here's how you can do it:
from django.db import models
class ServiceItem(models.Model):
title = models.CharField(max_length=120)
description = models.TextField(null=True, blank=True)
image = models.ImageField(null=True, blank=True, upload_to="service/")
class Meta:
db_table = "bishow_service_item"
verbose_name = "Custom Service Item"
verbose_name_plural = "Custom Service Items"
With this setup, in the Django admin interface, instead of "Service Items", you'll see "Custom Service Items" as the plural name, and instead of "Service Item", you'll see "Custom Service Item" as the singular name.
list_display
attribute in a Django ModelAdmin class
The list_display attribute in a Django ModelAdmin class is used to specify which fields of the model should be displayed in the list view of the Django admin interface.
When you register a model with the Django admin site, it provides a default list view where it shows a list of objects of that model. By default, Django admin will display a representation of each object that just says "object" followed by its primary key (e.g., "About object (1)
").
By specifying list_display
, you're telling Django admin to customize this default list view by displaying specific fields from your model instead of just the default representation.
For example, in your AboutAdmin class:
from django.contrib import admin
from .models import About
class AboutAdmin(admin.ModelAdmin):
list_display = ('title', 'description')
You've specified that in the list view for the About model, Django admin should display the title and description fields of each object.
This provides a more informative and user-friendly view of the data in the admin interface, making it easier for administrators to browse and manage the data.
Confirm that the AboutAdmin class is correctly registered with the About model. It should look like this:
"what is list_display
attribute?"
In Django, the list_display attribute in a ModelAdmin class is a sequence (typically a tuple) of field names, specifying which fields of the model should be displayed in the list view of the Django admin interface.
While you can use either a list or a tuple, it's a convention in Django to use a tuple for list_display. This is because list_display is not expected to be mutable; it's defining the structure of the admin interface, which should remain consistent.
However, since Python allows both lists and tuples to be used in most contexts interchangeably, you can technically use either. Here's an example showing list_display being defined with both a list and a tuple:
# Using a tuple
class MyModelAdmin(admin.ModelAdmin):
list_display = ('field1', 'field2', 'field3')
# Using a list (not recommended, but works)
class MyModelAdmin(admin.ModelAdmin):
list_display = ['field1', 'field2', 'field3']
Both of the above are valid and will achieve the same result. However, using a tuple is more consistent with Django's style and intent for list_display.
Preview image in admin column
how to display a preview
of the image directly in the Django admin interface
If you want to display a preview of the image directly in the Django admin interface without using an HTML <img>
tag, you can utilize Django's built-in functionality to generate thumbnail previews of images. Django's ImageField provides a Thumbnail widget that automatically generates a thumbnail preview for images.
Here's how you can implement it:
from django.contrib import admin
from django.utils.safestring import mark_safe
from .models import About
class AboutAdmin(admin.ModelAdmin):
list_display = ('title', 'description', 'display_image')
def display_image(self, obj):
if obj.image:
return mark_safe('<img src="{}" width="100" height="100" />'.format(obj.image.url))
else:
return 'No Image'
display_image.short_description = 'Image Preview'
admin.site.register(About, AboutAdmin)
In this code:
- We still define the display_image method to return an image tag.
- We use Django's mark_safe function to mark the string as safe HTML. This is necessary to prevent Django from escaping the HTML when rendering.
- If there is no image associated with the About object, we return a text saying "No Image".
- The
display_image
method is assigned to the list_display attribute to display the image preview along with other fields.
With this setup, the Django admin list view for the About model will display a preview of the image (if available) directly in the interface. If there's no image, it will display "No Image". Adjust the width and height attributes as needed to control the size of the displayed images.
Abstract
To reuse the display_image method without duplicating code, you can define it as a static method and use it across multiple ModelAdmin classes. Here's how you can refactor your code:
from django.contrib import admin
from django.utils.safestring import mark_safe
from .models import About, Project, ProjectItem
class ImageDisplayMixin:
@staticmethod
def display_image(obj):
if obj.image:
return mark_safe('<img src="{}" width="100" height="100" />'.format(obj.image.url))
else:
return 'No Image'
display_image.short_description = 'Image Preview'
class AboutAdmin(admin.ModelAdmin, ImageDisplayMixin):
list_display = ('title', 'description', 'display_image')
class ProjectAdmin(admin.ModelAdmin):
list_display = ('title', 'description')
class ProjectItemAdmin(admin.ModelAdmin, ImageDisplayMixin):
list_display = ('title', 'description', 'display_image')
admin.site.register(About, AboutAdmin)
admin.site.register(Project, ProjectAdmin)
admin.site.register(ProjectItem, ProjectItemAdmin)
In this code:
- We've created a mixin class called ImageDisplayMixin, which contains the display_image method.
- The display_image method is decorated with @staticmethod to indicate that it doesn't require access to instance data.
- Both
AboutAdmin
andProjectItemAdmin
classes inherit fromImageDisplayMixin
, allowing them to reuse the display_image method without duplicating code. - By using this approach, you avoid redundancy and keep your code DRY (Don't Repeat Yourself).
Remove add button in admin
how to remove add button in admin interface
Yes, you can remove the "Add About
" button from the Django admin interface if there is already one item present. This can be achieved by customizing the admin interface using the has_add_permission method in your ModelAdmin class.
Here's how you can do it:
from django.contrib import admin
from .models import About
class AboutAdmin(admin.ModelAdmin):
# other configurations for list_display, fields, etc.
def has_add_permission(self, request):
# Check if there are any existing About objects
if About.objects.exists():
# Return False to disable the "Add About" button
return False
# Return True to enable the "Add About" button
return True
admin.site.register(About, AboutAdmin)
In this code:
- We define the has_add_permission method in the AboutAdmin class.
- Inside this method, we check if there are any existing About objects in the database using About.objects.exists().
- If there are existing About objects, we return False to disable the "
Add About
" button. - If there are no existing About objects, we return True to enable the "
Add About
" button.
By implementing has_add_permission in this way, you can control whether the "Add About
" button is displayed based on the presence of existing About objects in the database. If there is already an About object, the button will be hidden, preventing users from adding more About objects.
The reason why HasAddPermissionMixin is not working as expected might be due to the order of inheritance in your ServiceAdmin class. In Python, the order of inheritance matters.
When you inherit from multiple classes, Python resolves method lookups in the order specified by the inheritance list. This means that if a method is defined in both the child class and one of its parent classes, the version of the method defined in the child class will take precedence.
In your case, HasAddPermissionMixin should come before admin.ModelAdmin in the inheritance list so that its has_add_permission method overrides the one from admin.ModelAdmin. Here's the corrected version:
from django.contrib import admin
from django.utils.safestring import mark_safe
from .models import About, Project, ProjectItem, Service, ServiceItem
class HasAddPermissionMixin:
"""
Mixin class to control the add permission based on the existence of objects.
"""
def has_add_permission(self, request):
model = self.model
return not model.objects.exists()
class ServiceAdmin(HasAddPermissionMixin, admin.ModelAdmin):
"""
Admin class for managing Service objects.
"""
list_display = ('title', 'description')
In this corrected version:
- HasAddPermissionMixin is listed before admin.ModelAdmin in the inheritance list of ServiceAdmin, ensuring that its has_add_permission method takes precedence.
- The ServiceAdmin class now inherits from HasAddPermissionMixin and admin.ModelAdmin in the correct order.
With this setup, HasAddPermissionMixin should work as expected in the ServiceAdmin class.
category in django
class ProjectItem(models.Model):
title = models.CharField(max_length=120)
description = models.TextField(null=True, blank=True)
image = models.ImageField(null=True, blank=True, upload_to="project/")
link = models.CharField(null=True, blank=True, max_length=120)
category = models.ForeignKey('ProjectCategory', on_delete=models.CASCADE, related_name='items')
class Meta:
db_table = "bishow_project_item"
verbose_name = "Project Item"
verbose_name_plural = "Project Items"
class ProjectCategory(models.Model):
name = models.CharField(max_length=120)
class Meta:
db_table = "bishow_project_category"
verbose_name = "Project Category"
verbose_name_plural = "Project Categories"
Rename app name in admin
To rename the app name in the Django admin interface,
you can customize the display name by providing a custom AppConfig for your app and then specifying the verbose name. Here's how you can do it:
Create an AppConfig class in your app's apps.py file:
Customizing Django Admin Display
class BlogItemAdmin(admin.ModelAdmin):
list_display = ('created')
# Define a custom method to display the value of the 'created_at' field with the custom name 'created'
def created(self, obj):
return obj.created_at
# Set a custom label for the column header in the admin interface
created.short_description = 'Created'
from django.contrib import admin
from .models import Blog, BlogItem
class BlogItemAdmin(admin.ModelAdmin):
list_display = ('title', 'description', 'image', 'published', 'created_at', 'publish_status')
# Specify the order of fields in the form
fields = ('title', 'description', 'image', 'published', 'updated_at')
# CUSTOMIZE the Column name of model name
def publish_status(self, obj):
return "Published" if obj.published else "Not Published"
publish_status.short_description = 'Publication Status'
# publish_status.admin_order_field = 'published'
admin.site.register(Blog, BlogAdmin)
Model Admin
Each registered admin.ModelAdmin class gets a set of CRUD pages. CRUD, besides being a very fun acronym, stands for: Create, Read, Update, and Delete, the actions you take on most pieces of data.
The default behavior of the admin.ModelAdmin class includes all the CRUD pages, so your new class can have an empty body, using just the pass
keyword.
Figure 5.3. The Django Admin is an app that ships with Django giving administrators the ability to create and modify registered Model objects