furry/recommendations/admin.py

192 lines
6.9 KiB
Python

"""
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]