# Django Admin Configuration
Configure Django admin interface with custom admin classes and functionality.
## Purpose
This command helps you create comprehensive Django admin configurations with advanced features and customizations.
## Usage
```
/admin
```
## What this command does
1. **Registers models** with custom admin classes
2. **Creates advanced admin interfaces** with filtering, search, and actions
3. **Adds inline editing** for related models
4. **Customizes list displays** and forms
5. **Implements admin actions** for bulk operations
## Example Output
```python
# admin.py
from django.contrib import admin
from django.utils.html import format_html
from django.urls import reverse
from django.utils.safestring import mark_safe
from .models import Post, Category, Tag, Comment
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
"""Admin configuration for Category model."""
list_display = ['name', 'slug', 'post_count', 'created_at']
list_filter = ['created_at']
search_fields = ['name', 'description']
prepopulated_fields = {'slug': ('name',)}
readonly_fields = ['created_at', 'updated_at']
def post_count(self, obj):
"""Display number of posts in this category."""
count = obj.posts.count()
url = reverse('admin:blog_post_changelist') + f'?category__id__exact={obj.id}'
return format_html('{} posts', url, count)
post_count.short_description = 'Posts'
class CommentInline(admin.TabularInline):
"""Inline admin for comments."""
model = Comment
extra = 0
readonly_fields = ['created_at', 'author']
fields = ['author', 'content', 'is_approved', 'created_at']
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
"""Advanced admin configuration for Post model."""
list_display = [
'title',
'author',
'category',
'status',
'view_count',
'created_at',
'post_preview'
]
list_filter = [
'status',
'category',
'created_at',
'updated_at',
('author', admin.RelatedOnlyFieldListFilter)
]
search_fields = ['title', 'content', 'author__username']
prepopulated_fields = {'slug': ('title',)}
readonly_fields = ['created_at', 'updated_at', 'view_count', 'post_preview']
# Custom form layout
fieldsets = (
('Content', {
'fields': ('title', 'slug', 'content', 'status')
}),
('Metadata', {
'fields': ('author', 'category', 'tags'),
'classes': ('collapse',)
}),
('SEO', {
'fields': ('meta_description', 'meta_keywords'),
'classes': ('collapse',)
}),
('Timestamps', {
'fields': ('created_at', 'updated_at', 'view_count'),
'classes': ('collapse',)
}),
)
# Many-to-many field display
filter_horizontal = ['tags']
# Inline models
inlines = [CommentInline]
# Custom list display methods
def post_preview(self, obj):
"""Show thumbnail preview of post."""
if obj.featured_image:
return format_html(
'
',
obj.featured_image.url
)
return "No image"
post_preview.short_description = 'Preview'
# Custom admin actions
actions = ['make_published', 'make_draft', 'duplicate_posts']
def make_published(self, request, queryset):
"""Bulk action to publish selected posts."""
updated = queryset.update(status='published')
self.message_user(
request,
f'{updated} posts were successfully marked as published.'
)
make_published.short_description = "Mark selected posts as published"
def make_draft(self, request, queryset):
"""Bulk action to set selected posts as draft."""
updated = queryset.update(status='draft')
self.message_user(
request,
f'{updated} posts were successfully marked as draft.'
)
make_draft.short_description = "Mark selected posts as draft"
def duplicate_posts(self, request, queryset):
"""Bulk action to duplicate selected posts."""
count = 0
for post in queryset:
post.pk = None # Create new instance
post.title = f"Copy of {post.title}"
post.slug = f"copy-of-{post.slug}"
post.status = 'draft'
post.save()
count += 1
self.message_user(
request,
f'{count} posts were successfully duplicated.'
)
duplicate_posts.short_description = "Duplicate selected posts"
@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
"""Admin configuration for Tag model."""
list_display = ['name', 'slug', 'post_count', 'color_preview']
search_fields = ['name']
prepopulated_fields = {'slug': ('name',)}
def post_count(self, obj):
"""Display number of posts with this tag."""
return obj.posts.count()
post_count.short_description = 'Posts'
def color_preview(self, obj):
"""Show color preview if tag has color field."""
if hasattr(obj, 'color') and obj.color:
return format_html(
'{}',
obj.color,
obj.name
)
return obj.name
color_preview.short_description = 'Preview'
@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
"""Admin configuration for Comment model."""
list_display = ['author', 'post', 'content_preview', 'is_approved', 'created_at']
list_filter = ['is_approved', 'created_at', 'post__category']
search_fields = ['content', 'author__username', 'post__title']
readonly_fields = ['created_at', 'updated_at']
actions = ['approve_comments', 'disapprove_comments']
def content_preview(self, obj):
"""Show truncated content preview."""
return obj.content[:50] + "..." if len(obj.content) > 50 else obj.content
content_preview.short_description = 'Content'
def approve_comments(self, request, queryset):
"""Bulk approve comments."""
updated = queryset.update(is_approved=True)
self.message_user(request, f'{updated} comments were approved.')
approve_comments.short_description = "Approve selected comments"
def disapprove_comments(self, request, queryset):
"""Bulk disapprove comments."""
updated = queryset.update(is_approved=False)
self.message_user(request, f'{updated} comments were disapproved.')
disapprove_comments.short_description = "Disapprove selected comments"
# Custom admin site configuration
admin.site.site_header = "Blog Administration"
admin.site.site_title = "Blog Admin Portal"
admin.site.index_title = "Welcome to Blog Administration"
```
## Advanced Features
### Custom List Display
- **Thumbnail previews** for images
- **Related object counts** with links
- **Status indicators** with colors
- **Custom formatting** for data display
### Filtering and Search
- **Advanced filters** including date ranges
- **Related field filtering** for foreign keys
- **Search across multiple fields** including relations
- **Custom filter classes** for complex queries
### Inline Editing
- **TabularInline** for compact editing
- **StackedInline** for detailed forms
- **Custom inline forms** with additional functionality
- **Readonly fields** in inlines
### Bulk Actions
- **Status changes** for multiple objects
- **Data export** functionality
- **Batch operations** for efficiency
- **Custom business logic** in actions
### Form Customization
- **Fieldsets** for organized layouts
- **Collapsed sections** for advanced options
- **Custom widgets** for better UX
- **Validation** and error handling
## Security Considerations
- **Permission checks** in custom methods
- **Input sanitization** in admin actions
- **CSRF protection** (automatic)
- **User authentication** (built-in)
## Performance Optimization
```python
# Optimize queries with select_related/prefetch_related
class PostAdmin(admin.ModelAdmin):
def get_queryset(self, request):
queryset = super().get_queryset(request)
return queryset.select_related('author', 'category').prefetch_related('tags')
```
## Custom Admin Templates
```python
# Override admin templates
class PostAdmin(admin.ModelAdmin):
change_form_template = 'admin/blog/post/change_form.html'
change_list_template = 'admin/blog/post/change_list.html'
```