diff --git a/backend/competition/admin.py b/backend/competition/admin.py index 5f1525d..aa4c63e 100644 --- a/backend/competition/admin.py +++ b/backend/competition/admin.py @@ -54,7 +54,7 @@ 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'), + 'fields': ('score_calculation_type', 'active_formula'), 'description': '配置得分计算方式:默认加权平均或使用评分公式' }), ) @@ -183,7 +183,7 @@ class ScoreFormulaAdmin(ModelAdmin): }), ('公式配置', { 'fields': ('formula',), - 'description': '使用维度名称作为变量,例如: 创新性 * 0.3 + 实用性 * 0.5 + 演示效果 * 0.2' + 'description': '使用 dimension_X 作为变量(X为维度ID),例如: (dimension_1 + dimension_2) / 2' }), ('公式设置', { 'fields': ('is_active', 'is_default') diff --git a/backend/competition/migrations/0010_remove_competition_custom_score_formula.py b/backend/competition/migrations/0010_remove_competition_custom_score_formula.py new file mode 100644 index 0000000..ce8f0db --- /dev/null +++ b/backend/competition/migrations/0010_remove_competition_custom_score_formula.py @@ -0,0 +1,17 @@ +# Generated by Django 6.0.1 on 2026-03-20 06:19 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('competition', '0009_competition_active_formula_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='competition', + name='custom_score_formula', + ), + ] diff --git a/backend/competition/models.py b/backend/competition/models.py index fa171c3..1d923d3 100644 --- a/backend/competition/models.py +++ b/backend/competition/models.py @@ -44,7 +44,6 @@ class Competition(models.Model): 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="是否启用") created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") @@ -178,14 +177,13 @@ class Project(models.Model): def calculate_score(self): """ 计算项目得分 - 支持三种模式: + 支持两种模式: 1. 默认加权平均:每个评委的得分 = sum(维度分数 × 维度权重),然后所有评委取平均 2. 使用评分公式:使用比赛关联的评分公式计算最终得分 - 3. 自定义算式(比赛级别):使用比赛级别的 custom_score_formula 计算最终得分 - 自定义算式变量格式: + 评分公式变量格式: - dimension_X: 第X个维度的平均分(所有评委对该维度的平均分) - - 也可以使用维度名称作为变量 + - 例如: (dimension_1 + dimension_2) / 2 """ scores = self.scores.all() if not scores.exists(): @@ -198,9 +196,6 @@ class Project(models.Model): 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) - return self._calculate_default_score(scores) def _calculate_default_score(self, scores): @@ -230,10 +225,11 @@ class Project(models.Model): self.save() return avg_score - def _calculate_custom_score(self, scores, formula): + def _calculate_formula_score(self, scores, formula_obj): """ - 自定义算式模式(比赛级别) - 使用比赛配置的自定义算式计算得分 + 公式配置模式(使用 ScoreFormula 模型) + 使用公式配置中的公式计算得分 + 变量格式: dimension_X (X为维度ID) """ dimension_scores = {} @@ -243,36 +239,6 @@ class Project(models.Model): if dim_scores.exists(): avg = sum(float(s.score) for s in dim_scores) / dim_scores.count() dimension_scores[f'dimension_{dimension.id}'] = avg - dimension_scores[dimension.name] = avg - - if not dimension_scores: - self.final_score = 0 - self.save() - return 0 - - try: - result = eval(formula, {"__builtins__": {}}, dimension_scores) - final_score = float(result) - self.final_score = round(final_score, 2) - self.save() - return self.final_score - except Exception as e: - print(f"算式计算错误: {e}, formula: {formula}, values: {dimension_scores}") - return self._calculate_default_score(scores) - - def _calculate_formula_score(self, scores, formula_obj): - """ - 公式配置模式(使用 ScoreFormula 模型) - 使用公式配置中的公式计算得分 - """ - dimension_scores = {} - - dimensions = self.competition.score_dimensions.all() - for dimension in dimensions: - dim_scores = scores.filter(dimension=dimension) - if dim_scores.exists(): - avg = sum(float(s.score) for s in dim_scores) / dim_scores.count() - dimension_scores[dimension.name] = avg if not dimension_scores: self.final_score = 0