diff --git a/backend/competition/admin.py b/backend/competition/admin.py index d50dcbf..5f1525d 100644 --- a/backend/competition/admin.py +++ b/backend/competition/admin.py @@ -40,6 +40,7 @@ class CompetitionAdmin(ModelAdmin): list_filter = ['status', 'allow_contestant_grading', 'is_active'] search_fields = ['title', 'description'] inlines = [ScoreDimensionInline, ScoreFormulaInline] + autocomplete_fields = ['active_formula'] fieldsets = ( ('基本信息', { @@ -52,6 +53,10 @@ class CompetitionAdmin(ModelAdmin): ('时间和状态', { 'fields': ('start_time', 'end_time', 'status', 'project_visibility', 'allow_contestant_grading', 'is_active') }), + ('评分配置', { + 'fields': ('score_calculation_type', 'custom_score_formula', 'active_formula'), + 'description': '配置得分计算方式:默认加权平均或使用评分公式' + }), ) actions = ['make_published', 'make_ended'] @@ -192,9 +197,9 @@ class ScoreFormulaAdmin(ModelAdmin): class Media: css = { - 'all': ('competition/admin/css/competition-admin.css',) + 'all': ('competition/admin/css/competition-admin.css', 'competition/admin/css/formula-editor.css') } - js = ('competition/admin/js/competition-admin.js',) + js = ('competition/admin/js/competition-admin.js', 'competition/admin/js/formula-editor.js') admin.site.register(ScoreFormula, ScoreFormulaAdmin) diff --git a/backend/competition/migrations/0009_competition_active_formula_and_more.py b/backend/competition/migrations/0009_competition_active_formula_and_more.py new file mode 100644 index 0000000..db451bb --- /dev/null +++ b/backend/competition/migrations/0009_competition_active_formula_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 6.0.1 on 2026-03-20 06:07 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('competition', '0008_scoreformula'), + ] + + operations = [ + migrations.AddField( + model_name='competition', + name='active_formula', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='active_competitions', to='competition.scoreformula', verbose_name='启用的评分公式'), + ), + migrations.AlterField( + model_name='competition', + name='score_calculation_type', + field=models.CharField(choices=[('default', '默认加权平均'), ('formula', '使用评分公式')], default='default', max_length=20, verbose_name='得分计算方式'), + ), + ] diff --git a/backend/competition/models.py b/backend/competition/models.py index 7b20bb5..fa171c3 100644 --- a/backend/competition/models.py +++ b/backend/competition/models.py @@ -39,10 +39,11 @@ class Competition(models.Model): SCORE_CALCULATION_CHOICES = ( ('default', '默认加权平均'), - ('custom', '自定义算式'), + ('formula', '使用评分公式'), ) score_calculation_type = models.CharField(max_length=20, choices=SCORE_CALCULATION_CHOICES, default='default', verbose_name="得分计算方式") + active_formula = models.ForeignKey('ScoreFormula', on_delete=models.SET_NULL, null=True, blank=True, related_name='active_competitions', verbose_name="启用的评分公式") custom_score_formula = models.CharField(max_length=1000, blank=True, verbose_name="自定义得分算式", help_text="如使用自定义算式,将使用此公式计算最终得分。变量格式: dimension_维度ID,如 dimension_1, dimension_2") is_active = models.BooleanField(default=True, verbose_name="是否启用") @@ -179,8 +180,8 @@ class Project(models.Model): 计算项目得分 支持三种模式: 1. 默认加权平均:每个评委的得分 = sum(维度分数 × 维度权重),然后所有评委取平均 - 2. 自定义算式(比赛级别):使用比赛级别的 custom_score_formula 计算最终得分 - 3. 公式配置(公式级别):使用 ScoreFormula 模型中的公式配置 + 2. 使用评分公式:使用比赛关联的评分公式计算最终得分 + 3. 自定义算式(比赛级别):使用比赛级别的 custom_score_formula 计算最终得分 自定义算式变量格式: - dimension_X: 第X个维度的平均分(所有评委对该维度的平均分) @@ -194,14 +195,8 @@ class Project(models.Model): competition = self.competition - active_formula = ScoreFormula.objects.filter( - competition=competition, - is_active=True, - is_default=True - ).first() - - if active_formula: - return self._calculate_formula_score(scores, active_formula) + if competition.score_calculation_type == 'formula' and competition.active_formula: + return self._calculate_formula_score(scores, competition.active_formula) if competition.score_calculation_type == 'custom' and competition.custom_score_formula: return self._calculate_custom_score(scores, competition.custom_score_formula)