创赢未来评分系统 - 初始化提交(移除大文件)
All checks were successful
Deploy to Server / deploy (push) Successful in 18s
All checks were successful
Deploy to Server / deploy (push) Successful in 18s
This commit is contained in:
155
backend/competition/serializers.py
Normal file
155
backend/competition/serializers.py
Normal file
@@ -0,0 +1,155 @@
|
||||
from rest_framework import serializers
|
||||
from .models import Competition, CompetitionEnrollment, ScoreDimension, Project, ProjectFile, Score, Comment, HomePageConfig, CarouselItem
|
||||
from shop.serializers import WeChatUserSerializer
|
||||
|
||||
|
||||
class CarouselItemSerializer(serializers.ModelSerializer):
|
||||
display_image = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = CarouselItem
|
||||
fields = ['id', 'carousel_type', 'image', 'image_url', 'display_image',
|
||||
'title', 'subtitle', 'status', 'status_color', 'date', 'location',
|
||||
'order', 'is_active']
|
||||
|
||||
def get_display_image(self, obj):
|
||||
request = self.context.get('request')
|
||||
if obj.image:
|
||||
if request:
|
||||
return request.build_absolute_uri(obj.image.url)
|
||||
return obj.image.url
|
||||
return obj.image_url
|
||||
|
||||
|
||||
class HomePageConfigSerializer(serializers.ModelSerializer):
|
||||
display_banner = serializers.SerializerMethodField()
|
||||
carousel1_items = serializers.SerializerMethodField()
|
||||
carousel2_items = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = HomePageConfig
|
||||
fields = ['id', 'banner_image', 'banner_image_url', 'display_banner',
|
||||
'main_title', 'carousel1_title', 'carousel2_title',
|
||||
'organizer', 'undertaker', 'carousel1_items', 'carousel2_items']
|
||||
|
||||
def get_display_banner(self, obj):
|
||||
request = self.context.get('request')
|
||||
if obj.banner_image:
|
||||
if request:
|
||||
return request.build_absolute_uri(obj.banner_image.url)
|
||||
return obj.banner_image.url
|
||||
return obj.banner_image_url
|
||||
|
||||
def get_carousel1_items(self, obj):
|
||||
items = CarouselItem.objects.filter(carousel_type='carousel1', is_active=True)
|
||||
return CarouselItemSerializer(items, many=True, context=self.context).data
|
||||
|
||||
def get_carousel2_items(self, obj):
|
||||
items = CarouselItem.objects.filter(carousel_type='carousel2', is_active=True)
|
||||
return CarouselItemSerializer(items, many=True, context=self.context).data
|
||||
|
||||
|
||||
class ScoreDimensionSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ScoreDimension
|
||||
fields = ['id', 'name', 'description', 'weight', 'max_score', 'order']
|
||||
|
||||
class CompetitionSerializer(serializers.ModelSerializer):
|
||||
score_dimensions = ScoreDimensionSerializer(many=True, read_only=True)
|
||||
display_cover_image = serializers.SerializerMethodField()
|
||||
status_display = serializers.CharField(source='get_status_display', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Competition
|
||||
fields = ['id', 'title', 'description', 'rule_description', 'condition_description',
|
||||
'cover_image', 'cover_image_url', 'display_cover_image',
|
||||
'start_time', 'end_time', 'status', 'project_visibility', 'status_display', 'is_active',
|
||||
'score_dimensions', 'created_at']
|
||||
|
||||
def get_display_cover_image(self, obj):
|
||||
request = self.context.get('request')
|
||||
if obj.cover_image:
|
||||
if request:
|
||||
return request.build_absolute_uri(obj.cover_image.url)
|
||||
return obj.cover_image.url
|
||||
return obj.cover_image_url
|
||||
|
||||
class CompetitionEnrollmentSerializer(serializers.ModelSerializer):
|
||||
user = WeChatUserSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = CompetitionEnrollment
|
||||
fields = ['id', 'competition', 'user', 'role', 'status', 'created_at']
|
||||
read_only_fields = ['status']
|
||||
|
||||
class ProjectFileSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ProjectFile
|
||||
fields = ['id', 'project', 'file_type', 'file', 'file_url', 'name', 'created_at']
|
||||
|
||||
def validate_file(self, value):
|
||||
if not value:
|
||||
return value
|
||||
# 50MB limit
|
||||
limit_mb = 50
|
||||
if value.size > limit_mb * 1024 * 1024:
|
||||
raise serializers.ValidationError(f"文件大小不能超过 {limit_mb}MB")
|
||||
return value
|
||||
|
||||
class ProjectSerializer(serializers.ModelSerializer):
|
||||
files = ProjectFileSerializer(many=True, read_only=True)
|
||||
contestant_info = serializers.SerializerMethodField()
|
||||
display_cover_image = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Project
|
||||
fields = ['id', 'competition', 'contestant', 'title', 'description', 'team_info',
|
||||
'cover_image', 'cover_image_url', 'display_cover_image',
|
||||
'status', 'final_score', 'files', 'contestant_info', 'created_at']
|
||||
read_only_fields = ['final_score', 'contestant']
|
||||
|
||||
def get_contestant_info(self, obj):
|
||||
return {
|
||||
"nickname": obj.contestant.user.nickname,
|
||||
"avatar_url": obj.contestant.user.avatar_url
|
||||
}
|
||||
|
||||
def get_display_cover_image(self, obj):
|
||||
if obj.cover_image:
|
||||
return obj.cover_image.url
|
||||
return obj.cover_image_url
|
||||
|
||||
class ScoreSerializer(serializers.ModelSerializer):
|
||||
judge_name = serializers.CharField(source='judge.user.nickname', read_only=True)
|
||||
dimension_name = serializers.CharField(source='dimension.name', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Score
|
||||
fields = ['id', 'project', 'judge', 'dimension', 'score', 'judge_name', 'dimension_name', 'created_at']
|
||||
read_only_fields = ['judge']
|
||||
|
||||
class CommentSerializer(serializers.ModelSerializer):
|
||||
judge_name = serializers.CharField(source='judge.user.nickname', read_only=True)
|
||||
score = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['id', 'project', 'judge', 'content', 'judge_name', 'created_at', 'score']
|
||||
read_only_fields = ['judge']
|
||||
|
||||
def get_score(self, obj):
|
||||
scores = Score.objects.filter(project=obj.project, judge=obj.judge)
|
||||
if not scores.exists():
|
||||
return None
|
||||
|
||||
current_judge_total_score = 0
|
||||
current_judge_total_weight = 0
|
||||
|
||||
for score in scores:
|
||||
current_judge_total_score += score.score * score.dimension.weight
|
||||
current_judge_total_weight += score.dimension.weight
|
||||
|
||||
if current_judge_total_weight > 0:
|
||||
judge_score = current_judge_total_score / current_judge_total_weight
|
||||
return round(judge_score, 1)
|
||||
return None
|
||||
Reference in New Issue
Block a user