website/hub/services/admin/articles.py

126 lines
3.4 KiB
Python

"""
Admin configuration for Article model
"""
from django.contrib import admin
from django.utils.html import format_html
from django import forms
from django.core.exceptions import ValidationError
from ..models import Article
from .widgets import ImageLibraryWidget
class ArticleAdminForm(forms.ModelForm):
"""Custom form for Article admin with validation"""
class Meta:
model = Article
fields = "__all__"
widgets = {
"image_library": ImageLibraryWidget(),
}
def clean_title(self):
"""Validate title length"""
title = self.cleaned_data.get("title")
if title and len(title) > 50:
raise ValidationError("Title must be 50 characters or less.")
return title
def clean_excerpt(self):
"""Validate excerpt length"""
excerpt = self.cleaned_data.get("excerpt")
if excerpt and len(excerpt) > 200:
raise ValidationError("Excerpt must be 200 characters or less.")
return excerpt
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
"""Admin configuration for Article model"""
form = ArticleAdminForm
list_display = (
"title",
"author",
"image_preview",
"is_published",
"is_featured",
"article_date",
)
list_filter = (
"is_published",
"is_featured",
"author",
"related_service",
"related_consulting_partner",
"related_cloud_provider",
"article_date",
)
search_fields = ("title", "excerpt", "content", "meta_keywords")
prepopulated_fields = {"slug": ("title",)}
readonly_fields = ("created_at", "updated_at")
ordering = ("-article_date",)
fieldsets = (
(None, {"fields": ("title", "slug", "excerpt", "content", "meta_keywords")}),
(
"Images",
{
"fields": ("image_library",),
"description": "Select an image from the Image Library.",
},
),
(
"Publishing",
{"fields": ("author", "article_date", "is_published", "is_featured")},
),
(
"Relations",
{
"fields": (
"related_service",
"related_consulting_partner",
"related_cloud_provider",
),
"classes": ("collapse",),
},
),
(
"Metadata",
{
"fields": ("created_at", "updated_at"),
"classes": ("collapse",),
},
),
)
def image_preview(self, obj):
"""Display image preview in admin list view"""
image = obj.get_image
if image:
return format_html('<img src="{}" style="max-height: 50px;"/>', image.url)
return "No image"
image_preview.short_description = "Image"
def related_to_display(self, obj):
"""Display what this article is related to"""
return obj.related_to
related_to_display.short_description = "Related To"
def get_queryset(self, request):
"""Optimize queries by selecting related objects"""
return (
super()
.get_queryset(request)
.select_related(
"author",
"related_service",
"related_consulting_partner",
"related_cloud_provider",
)
)