192 lines
6.9 KiB
Python
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] |