This commit is contained in:
@@ -19,6 +19,19 @@ class CompetitionAdmin(ModelAdmin):
|
||||
search_fields = ['title', 'description']
|
||||
inlines = [ScoreDimensionInline]
|
||||
|
||||
fieldsets = (
|
||||
('基本信息', {
|
||||
'fields': ('title', 'description', 'rule_description', 'condition_description')
|
||||
}),
|
||||
('封面设置', {
|
||||
'fields': ('cover_image', 'cover_image_url'),
|
||||
'description': '封面图可以上传本地图片,也可以填写外部链接,优先显示本地上传的图片'
|
||||
}),
|
||||
('时间和状态', {
|
||||
'fields': ('start_time', 'end_time', 'status', 'is_active')
|
||||
}),
|
||||
)
|
||||
|
||||
actions = ['make_published', 'make_ended']
|
||||
|
||||
def make_published(self, request, queryset):
|
||||
@@ -51,6 +64,19 @@ class ProjectAdmin(ModelAdmin):
|
||||
search_fields = ['title', 'contestant__user__nickname']
|
||||
inlines = [ProjectFileInline]
|
||||
readonly_fields = ['final_score']
|
||||
|
||||
fieldsets = (
|
||||
('基本信息', {
|
||||
'fields': ('competition', 'contestant', 'title', 'description', 'team_info')
|
||||
}),
|
||||
('封面设置', {
|
||||
'fields': ('cover_image', 'cover_image_url'),
|
||||
'description': '封面图可以上传本地图片,也可以填写外部链接,优先显示本地上传的图片'
|
||||
}),
|
||||
('状态和得分', {
|
||||
'fields': ('status', 'final_score')
|
||||
}),
|
||||
)
|
||||
|
||||
@admin.register(Score)
|
||||
class ScoreAdmin(ModelAdmin):
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 6.0.1 on 2026-03-10 02:41
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('competition', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='competition',
|
||||
name='cover_image_url',
|
||||
field=models.URLField(blank=True, help_text='优先使用上传的图片', null=True, verbose_name='封面图URL'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='project',
|
||||
name='cover_image_url',
|
||||
field=models.URLField(blank=True, help_text='优先使用上传的图片', null=True, verbose_name='项目封面URL'),
|
||||
),
|
||||
]
|
||||
@@ -20,6 +20,7 @@ class Competition(models.Model):
|
||||
condition_description = models.TextField(verbose_name="参赛条件说明", blank=True)
|
||||
|
||||
cover_image = models.ImageField(upload_to='competitions/covers/', verbose_name="封面图", null=True, blank=True)
|
||||
cover_image_url = models.URLField(verbose_name="封面图URL", null=True, blank=True, help_text="优先使用上传的图片")
|
||||
|
||||
start_time = models.DateTimeField(verbose_name="开始时间")
|
||||
end_time = models.DateTimeField(verbose_name="结束时间")
|
||||
@@ -111,6 +112,7 @@ class Project(models.Model):
|
||||
team_info = models.TextField(verbose_name="团队介绍", blank=True)
|
||||
|
||||
cover_image = models.ImageField(upload_to='competitions/projects/covers/', verbose_name="项目封面", null=True, blank=True)
|
||||
cover_image_url = models.URLField(verbose_name="项目封面URL", null=True, blank=True, help_text="优先使用上传的图片")
|
||||
|
||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft', verbose_name="状态")
|
||||
|
||||
|
||||
@@ -9,13 +9,20 @@ class ScoreDimensionSerializer(serializers.ModelSerializer):
|
||||
|
||||
class CompetitionSerializer(serializers.ModelSerializer):
|
||||
score_dimensions = ScoreDimensionSerializer(many=True, read_only=True)
|
||||
display_cover_image = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Competition
|
||||
fields = ['id', 'title', 'description', 'rule_description', 'condition_description',
|
||||
'cover_image', 'start_time', 'end_time', 'status', 'is_active',
|
||||
'cover_image', 'cover_image_url', 'display_cover_image',
|
||||
'start_time', 'end_time', 'status', 'is_active',
|
||||
'score_dimensions', 'created_at']
|
||||
|
||||
def get_display_cover_image(self, obj):
|
||||
if obj.cover_image:
|
||||
return obj.cover_image.url
|
||||
return obj.cover_image_url
|
||||
|
||||
class CompetitionEnrollmentSerializer(serializers.ModelSerializer):
|
||||
user = WeChatUserSerializer(read_only=True)
|
||||
|
||||
@@ -41,11 +48,13 @@ class ProjectFileSerializer(serializers.ModelSerializer):
|
||||
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', 'status', 'final_score', 'files', 'contestant_info', 'created_at']
|
||||
'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):
|
||||
@@ -54,6 +63,11 @@ class ProjectSerializer(serializers.ModelSerializer):
|
||||
"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)
|
||||
|
||||
@@ -317,6 +317,37 @@ UNFOLD = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"title": "比赛管理",
|
||||
"separator": True,
|
||||
"items": [
|
||||
{
|
||||
"title": "比赛列表",
|
||||
"icon": "emoji_events",
|
||||
"link": reverse_lazy("admin:competition_competition_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "比赛人员/报名",
|
||||
"icon": "group_add",
|
||||
"link": reverse_lazy("admin:competition_competitionenrollment_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "参赛项目",
|
||||
"icon": "lightbulb",
|
||||
"link": reverse_lazy("admin:competition_project_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "评分记录",
|
||||
"icon": "score",
|
||||
"link": reverse_lazy("admin:competition_score_changelist"),
|
||||
},
|
||||
{
|
||||
"title": "评委评语",
|
||||
"icon": "rate_review",
|
||||
"link": reverse_lazy("admin:competition_comment_changelist"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"title": "系统配置",
|
||||
"separator": True,
|
||||
|
||||
Reference in New Issue
Block a user