website/hub/services/admin/articles.py
2025-06-06 14:53:49 +02:00

90 lines
2.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
class ArticleAdminForm(forms.ModelForm):
"""Custom form for Article admin with validation"""
class Meta:
model = Article
fields = "__all__"
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",
"created_at",
)
list_filter = (
"is_published",
"is_featured",
"author",
"related_service",
"related_consulting_partner",
"related_cloud_provider",
"created_at",
)
search_fields = ("title", "excerpt", "content", "meta_keywords")
prepopulated_fields = {"slug": ("title",)}
readonly_fields = ("created_at", "updated_at")
def image_preview(self, obj):
"""Display image preview in admin list view"""
if obj.image:
return format_html(
'<img src="{}" style="max-height: 50px;"/>', obj.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",
)
)