""" Recommendation Engine Admin Interface """ from django.contrib import admin from django.utils.html import format_html from django.urls import reverse from django.db.models import Count, Avg, Sum from .models import ( UserBehavior, UserProfile, ProductSimilarity, Recommendation, RecommendationModel, ABTest, RecommendationAnalytics ) @admin.register(UserBehavior) class UserBehaviorAdmin(admin.ModelAdmin): list_display = ['user', 'behavior_type', 'product', 'created_at', 'ip_address'] list_filter = ['behavior_type', 'created_at', 'user'] search_fields = ['user__username', 'product__name'] readonly_fields = ['id', 'created_at'] date_hierarchy = 'created_at' def get_queryset(self, request): return super().get_queryset(request).select_related('user', 'product') @admin.register(UserProfile) class UserProfileAdmin(admin.ModelAdmin): list_display = ['user', 'engagement_score', 'loyalty_level', 'total_purchases', 'last_active'] list_filter = ['loyalty_level', 'last_active'] search_fields = ['user__username'] readonly_fields = ['last_updated'] fieldsets = ( ('User Info', { 'fields': ('user', 'engagement_score', 'loyalty_level') }), ('Preferences', { 'fields': ('preferred_categories', 'preferred_fursuit_types', 'preferred_price_range', 'preferred_colors') }), ('Metrics', { 'fields': ('avg_session_duration', 'total_purchases', 'total_views', 'total_searches') }), ('ML Features', { 'fields': ('feature_vector', 'last_updated') }), ) def get_queryset(self, request): return super().get_queryset(request).select_related('user') @admin.register(ProductSimilarity) class ProductSimilarityAdmin(admin.ModelAdmin): list_display = ['product', 'similar_product', 'similarity_score', 'similarity_type', 'updated_at'] list_filter = ['similarity_type', 'updated_at'] search_fields = ['product__name', 'similar_product__name'] readonly_fields = ['created_at', 'updated_at'] def get_queryset(self, request): return super().get_queryset(request).select_related('product', 'similar_product') @admin.register(Recommendation) class RecommendationAdmin(admin.ModelAdmin): list_display = ['user', 'product', 'recommendation_type', 'confidence_score', 'is_clicked', 'is_purchased', 'created_at'] list_filter = ['recommendation_type', 'is_clicked', 'is_purchased', 'created_at'] search_fields = ['user__username', 'product__name'] readonly_fields = ['id', 'created_at'] date_hierarchy = 'created_at' fieldsets = ( ('Recommendation Info', { 'fields': ('user', 'product', 'recommendation_type', 'confidence_score', 'reason') }), ('Performance', { 'fields': ('is_clicked', 'is_purchased') }), ('Timing', { 'fields': ('created_at', 'expires_at') }), ) def get_queryset(self, request): return super().get_queryset(request).select_related('user', 'product') @admin.register(RecommendationModel) class RecommendationModelAdmin(admin.ModelAdmin): list_display = ['model_name', 'model_type', 'model_version', 'accuracy_score', 'is_active', 'trained_at'] list_filter = ['model_type', 'is_active', 'trained_at'] search_fields = ['model_name'] readonly_fields = ['id', 'created_at', 'trained_at'] fieldsets = ( ('Model Info', { 'fields': ('model_type', 'model_name', 'model_version', 'model_file') }), ('Parameters', { 'fields': ('model_parameters',) }), ('Performance', { 'fields': ('training_data_size', 'accuracy_score', 'precision_score', 'recall_score', 'f1_score') }), ('Status', { 'fields': ('is_active', 'created_at', 'trained_at') }), ) @admin.register(ABTest) class ABTestAdmin(admin.ModelAdmin): list_display = ['test_name', 'test_type', 'status', 'traffic_split', 'winner', 'created_by'] list_filter = ['status', 'test_type', 'created_at'] search_fields = ['test_name', 'description'] readonly_fields = ['id', 'created_at'] fieldsets = ( ('Test Info', { 'fields': ('test_name', 'description', 'test_type', 'created_by') }), ('Variants', { 'fields': ('variant_a', 'variant_b', 'traffic_split') }), ('Status', { 'fields': ('status', 'start_date', 'end_date') }), ('Results', { 'fields': ('variant_a_conversion', 'variant_b_conversion', 'statistical_significance', 'winner') }), ) @admin.register(RecommendationAnalytics) class RecommendationAnalyticsAdmin(admin.ModelAdmin): list_display = ['date', 'total_recommendations', 'total_clicks', 'total_purchases', 'click_through_rate', 'conversion_rate'] list_filter = ['date'] readonly_fields = ['date'] date_hierarchy = 'date' def click_through_rate(self, obj): if obj.total_recommendations > 0: return f"{(obj.total_clicks / obj.total_recommendations * 100):.1f}%" return "0%" click_through_rate.short_description = 'CTR' def conversion_rate(self, obj): if obj.total_clicks > 0: return f"{(obj.total_purchases / obj.total_clicks * 100):.1f}%" return "0%" conversion_rate.short_description = 'Conversion Rate' # Custom Admin Actions @admin.action(description="Update User Engagement Scores") def update_engagement_scores(modeladmin, request, queryset): for profile in queryset: profile.update_engagement_score() modeladmin.message_user(request, f"Updated engagement scores for {queryset.count()} profiles.") @admin.action(description="Train Recommendation Models") def train_models(modeladmin, request, queryset): from .services import RecommendationService service = RecommendationService() for model in queryset: trained_model = service.train_recommendation_model(model.model_type) modeladmin.message_user(request, f"Trained model: {trained_model.model_name}") @admin.action(description="Update Product Similarities") def update_similarities(modeladmin, request, queryset): from .services import RecommendationService service = RecommendationService() service.update_product_similarities() modeladmin.message_user(request, "Updated product similarities.") @admin.action(description="Update Analytics") def update_analytics(modeladmin, request, queryset): from .services import RecommendationService service = RecommendationService() analytics = service.update_analytics() modeladmin.message_user(request, f"Updated analytics for {analytics.date}") # Add actions to admin classes UserProfileAdmin.actions = [update_engagement_scores] RecommendationModelAdmin.actions = [train_models] ProductSimilarityAdmin.actions = [update_similarities] RecommendationAnalyticsAdmin.actions = [update_analytics]