from django.contrib import admin from django.utils.html import format_html from unfold.admin import ModelAdmin from unfold.decorators import display from .models import Review, ReviewHelpfulVote @admin.register(Review) class ReviewAdmin(ModelAdmin): list_display = [ 'id', 'user_link', 'entity_type', 'entity_link', 'rating_display', 'title', 'moderation_status_badge', 'helpful_score', 'created', ] list_filter = [ 'moderation_status', 'rating', 'created', 'content_type', ] search_fields = [ 'title', 'content', 'user__username', 'user__email', ] readonly_fields = [ 'user', 'content_type', 'object_id', 'content_object', 'helpful_votes', 'total_votes', 'helpful_percentage', 'created', 'modified', ] fieldsets = ( ('Review Information', { 'fields': ( 'user', 'content_type', 'object_id', 'content_object', 'title', 'content', 'rating', ) }), ('Visit Details', { 'fields': ( 'visit_date', 'wait_time_minutes', ) }), ('Voting Statistics', { 'fields': ( 'helpful_votes', 'total_votes', 'helpful_percentage', ) }), ('Moderation', { 'fields': ( 'moderation_status', 'moderation_notes', 'moderated_by', 'moderated_at', ) }), ('Timestamps', { 'fields': ( 'created', 'modified', ) }), ) list_per_page = 50 @display(description='User', ordering='user__username') def user_link(self, obj): from django.urls import reverse url = reverse('admin:users_user_change', args=[obj.user.pk]) return format_html('{}', url, obj.user.username) @display(description='Entity Type', ordering='content_type') def entity_type(self, obj): return obj.content_type.model.title() @display(description='Entity') def entity_link(self, obj): if obj.content_object: from django.urls import reverse model_name = obj.content_type.model url = reverse(f'admin:entities_{model_name}_change', args=[obj.object_id]) return format_html('{}', url, str(obj.content_object)) return f"ID: {obj.object_id}" @display(description='Rating', ordering='rating') def rating_display(self, obj): stars = '⭐' * obj.rating return format_html('{}', obj.rating, stars) @display(description='Status', ordering='moderation_status') def moderation_status_badge(self, obj): colors = { 'pending': '#FFA500', 'approved': '#28A745', 'rejected': '#DC3545', } color = colors.get(obj.moderation_status, '#6C757D') return format_html( '{}', color, obj.get_moderation_status_display() ) @display(description='Helpful Score') def helpful_score(self, obj): if obj.total_votes == 0: return "No votes yet" percentage = obj.helpful_percentage return f"{obj.helpful_votes}/{obj.total_votes} ({percentage:.0f}%)" def has_add_permission(self, request): # Reviews should only be created by users via API return False def has_delete_permission(self, request, obj=None): # Only superusers can delete reviews return request.user.is_superuser actions = ['approve_reviews', 'reject_reviews'] @admin.action(description='Approve selected reviews') def approve_reviews(self, request, queryset): count = 0 for review in queryset.filter(moderation_status='pending'): review.approve(request.user, 'Bulk approved from admin') count += 1 self.message_user(request, f'{count} reviews approved.') @admin.action(description='Reject selected reviews') def reject_reviews(self, request, queryset): count = 0 for review in queryset.filter(moderation_status='pending'): review.reject(request.user, 'Bulk rejected from admin') count += 1 self.message_user(request, f'{count} reviews rejected.') @admin.register(ReviewHelpfulVote) class ReviewHelpfulVoteAdmin(ModelAdmin): list_display = [ 'id', 'review_link', 'user_link', 'vote_type', 'created', ] list_filter = [ 'is_helpful', 'created', ] search_fields = [ 'review__title', 'user__username', 'user__email', ] readonly_fields = [ 'review', 'user', 'is_helpful', 'created', 'modified', ] list_per_page = 50 @display(description='Review', ordering='review__title') def review_link(self, obj): from django.urls import reverse url = reverse('admin:reviews_review_change', args=[obj.review.pk]) return format_html('{}', url, obj.review.title) @display(description='User', ordering='user__username') def user_link(self, obj): from django.urls import reverse url = reverse('admin:users_user_change', args=[obj.user.pk]) return format_html('{}', url, obj.user.username) @display(description='Vote', ordering='is_helpful') def vote_type(self, obj): if obj.is_helpful: return format_html('👍 Helpful') else: return format_html('👎 Not Helpful') def has_add_permission(self, request): # Votes should only be created by users via API return False def has_change_permission(self, request, obj=None): # Votes should not be changed after creation return False def has_delete_permission(self, request, obj=None): # Only superusers can delete votes return request.user.is_superuser