from django.contrib import admin from django.utils.translation import gettext_lazy as _ from unfold.decorators import display from unfold.admin import ModelAdmin, TabularInline, StackedInline from unfold.contrib.forms.widgets import WysiwygWidget from unfold.widgets import UnfoldAdminTextareaWidget, UnfoldAdminTextInputWidget, UnfoldAdminExpandableTextareaWidget from utils.multilang_json_widget import MultiLanguageJSONWidget from django import forms from .models import Blog, BlogContent from utils.admin import project_admin_site class BlogContentForm(forms.ModelForm): """ Custom form for BlogContent to use WysiwygWidget for content field """ class Meta: model = BlogContent fields = '__all__' widgets = { 'title': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminExpandableTextareaWidget), } class BlogAdminForm(forms.ModelForm): class Meta: model = Blog fields = '__all__' widgets = { # You can switch between UnfoldAdminTextInputWidget, UnfoldAdminExpandableTextareaWidget,UnfoldAdminTextareaWidget or WysiwygWidget 'title': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminExpandableTextareaWidget), 'slogan': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextareaWidget), 'summary': MultiLanguageJSONWidget(input_widget_class=WysiwygWidget), 'slug': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), } # ADD THIS METHOD: def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Explicitly tell the form these fields are required # so the admin template renders the red star self.fields['title'].required = True self.fields['slogan'].required = True class BlogContentInline(StackedInline): """ Inline admin for BlogContent in Blog admin """ model = BlogContent form = BlogContentForm extra = 1 fields = ('title', 'content', 'slug', 'image', 'order') ordering = ['order'] @admin.register(Blog, site=project_admin_site) class BlogAdmin(ModelAdmin): """ Admin interface for Blog model using Django unfold """ form = BlogAdminForm list_display = ('title_info', 'slogan', 'views_count', 'created_at', 'updated_at') list_filter = ('created_at', 'updated_at') search_fields = ('title', 'slogan', 'summary') # prepopulated_fields = {'slug': ('title',)} readonly_fields = ('views_count', 'created_at', 'updated_at') fieldsets = ( (_('Basic Information'), { 'fields': ('title', 'slug', 'thumbnail', 'slogan') }), (_('Content'), { 'fields': ('summary',) }), (_('Statistics'), { 'fields': ('views_count',), 'classes': ('collapse',) }), (_('Timestamps'), { 'fields': ('created_at', 'updated_at'), 'classes': ('collapse',) }), ) inlines = [BlogContentInline] @display(description=_('Title'), ) def title_info(self, obj): return str(obj.title) def get_queryset(self, request): queryset = super().get_queryset(request) print(f'--get_queryset-->{queryset}') for blog in queryset: print(f'-get_queryset-blog-->{blog.title}') return queryset.prefetch_related('contents') @admin.register(BlogContent, site=project_admin_site) class BlogContentAdmin(ModelAdmin): """ Admin interface for BlogContent model using Django unfold """ form = BlogContentForm list_display = ('title_info', 'blog', 'order', 'created_at', 'updated_at') list_filter = ('blog', 'created_at', 'updated_at') search_fields = ('title', 'content', 'blog__title') list_select_related = ('blog',) fieldsets = ( (_('Basic Information'), { 'fields': ('blog', 'title', 'slug', 'order') }), (_('Content'), { 'fields': ('content', 'image') }), (_('Timestamps'), { 'fields': ('created_at', 'updated_at'), 'classes': ('collapse',) }), ) readonly_fields = ('created_at', 'updated_at') @display(description=_('Title'), ) def title_info(self, obj): return str(obj.title)