This commit is contained in:
@@ -28,7 +28,7 @@ class CompetitionAdmin(ModelAdmin):
|
||||
'description': '封面图可以上传本地图片,也可以填写外部链接,优先显示本地上传的图片'
|
||||
}),
|
||||
('时间和状态', {
|
||||
'fields': ('start_time', 'end_time', 'status', 'is_active')
|
||||
'fields': ('start_time', 'end_time', 'status', 'project_visibility', 'is_active')
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 6.0.1 on 2026-03-10 06:20
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('competition', '0002_competition_cover_image_url_project_cover_image_url'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='competition',
|
||||
name='project_visibility',
|
||||
field=models.CharField(choices=[('public', '公开可见'), ('contestant', '选手及以上可见'), ('guest', '嘉宾及评委可见'), ('judge', '仅评委可见')], default='public', max_length=20, verbose_name='项目可见性'),
|
||||
),
|
||||
]
|
||||
@@ -14,6 +14,13 @@ class Competition(models.Model):
|
||||
('ended', '已结束'),
|
||||
)
|
||||
|
||||
PROJECT_VISIBILITY_CHOICES = (
|
||||
('public', '公开可见'),
|
||||
('contestant', '选手及以上可见'),
|
||||
('guest', '嘉宾及评委可见'),
|
||||
('judge', '仅评委可见'),
|
||||
)
|
||||
|
||||
title = models.CharField(max_length=200, verbose_name="比赛名称")
|
||||
description = models.TextField(verbose_name="比赛简介")
|
||||
rule_description = models.TextField(verbose_name="规则说明")
|
||||
@@ -26,6 +33,7 @@ class Competition(models.Model):
|
||||
end_time = models.DateTimeField(verbose_name="结束时间")
|
||||
|
||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft', verbose_name="状态")
|
||||
project_visibility = models.CharField(max_length=20, choices=PROJECT_VISIBILITY_CHOICES, default='public', verbose_name="项目可见性")
|
||||
|
||||
is_active = models.BooleanField(default=True, verbose_name="是否启用")
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
|
||||
|
||||
@@ -16,7 +16,7 @@ class CompetitionSerializer(serializers.ModelSerializer):
|
||||
model = Competition
|
||||
fields = ['id', 'title', 'description', 'rule_description', 'condition_description',
|
||||
'cover_image', 'cover_image_url', 'display_cover_image',
|
||||
'start_time', 'end_time', 'status', 'status_display', 'is_active',
|
||||
'start_time', 'end_time', 'status', 'project_visibility', 'status_display', 'is_active',
|
||||
'score_dimensions', 'created_at']
|
||||
|
||||
def get_display_cover_image(self, obj):
|
||||
|
||||
@@ -112,30 +112,39 @@ class ProjectViewSet(viewsets.ModelViewSet):
|
||||
if contestant_id:
|
||||
queryset = queryset.filter(contestant_id=contestant_id)
|
||||
|
||||
# 如果是普通用户,只能看到已提交的项目,或者自己草稿的项目
|
||||
user = get_current_wechat_user(self.request)
|
||||
|
||||
# 1. 基础条件:公开可见且已提交的项目
|
||||
q = Q(competition__project_visibility='public', status='submitted')
|
||||
|
||||
if user:
|
||||
# 查找用户在这个比赛中的角色
|
||||
# 如果是评委,可以看到所有项目(包括草稿吗?通常评委只看提交的)
|
||||
# 这里简化:评委看所有submitted,用户看所有submitted + 自己的draft
|
||||
|
||||
# 找到用户参与的所有比赛角色
|
||||
enrollments = CompetitionEnrollment.objects.filter(user=user)
|
||||
judge_competitions = enrollments.filter(role='judge').values_list('competition_id', flat=True)
|
||||
|
||||
# 基本查询:所有已提交的项目
|
||||
q = Q(status='submitted')
|
||||
|
||||
# 加上自己创建的项目 (即使是draft)
|
||||
# 2. 用户自己的项目(始终可见,包括草稿)
|
||||
q |= Q(contestant__user=user)
|
||||
|
||||
# 加上自己是评委的比赛的所有项目 (通常评委只看submitted,但如果需要预审可以看draft,这里假设只看submitted)
|
||||
# q |= Q(competition__in=judge_competitions)
|
||||
# 3. 基于角色的可见性
|
||||
# 获取用户已通过审核的报名信息
|
||||
enrollments = CompetitionEnrollment.objects.filter(user=user, status='approved')
|
||||
|
||||
queryset = queryset.filter(q)
|
||||
else:
|
||||
# 未登录用户只能看已提交
|
||||
queryset = queryset.filter(status='submitted')
|
||||
# 获取各角色的比赛ID集合
|
||||
judge_comp_ids = set(enrollments.filter(role='judge').values_list('competition_id', flat=True))
|
||||
guest_comp_ids = set(enrollments.filter(role='guest').values_list('competition_id', flat=True))
|
||||
contestant_comp_ids = set(enrollments.filter(role='contestant').values_list('competition_id', flat=True))
|
||||
|
||||
# 'judge' 可见性:仅评委可见
|
||||
if judge_comp_ids:
|
||||
q |= Q(competition__project_visibility='judge', competition__in=judge_comp_ids, status='submitted')
|
||||
|
||||
# 'guest' 可见性:嘉宾及评委可见
|
||||
guest_access_ids = judge_comp_ids | guest_comp_ids
|
||||
if guest_access_ids:
|
||||
q |= Q(competition__project_visibility='guest', competition__in=guest_access_ids, status='submitted')
|
||||
|
||||
# 'contestant' 可见性:选手及以上可见(包括评委、嘉宾)
|
||||
contestant_access_ids = judge_comp_ids | guest_comp_ids | contestant_comp_ids
|
||||
if contestant_access_ids:
|
||||
q |= Q(competition__project_visibility='contestant', competition__in=contestant_access_ids, status='submitted')
|
||||
|
||||
queryset = queryset.filter(q)
|
||||
|
||||
return queryset.order_by('-final_score', '-created_at')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user