You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django模型Choice字段如何为选项配置对应分值实现选型计分

Django模型Choice字段绑定分值实现方案

方案一:兼容存量数据(推荐已上线项目使用)

不需要修改现有数据库结构,不需要迁移数据,仅通过新增映射关系和属性方法即可实现分值获取。
直接修改models.py对应模型代码:

class Survey_Answer(models.Model):
    
    # 原有选项配置完全保留,不影响已存的历史数据
    CHOICES = [('Disagree Strongly', 'Disagree Strongly'),
            ('Disagree', 'Disagree'),
            ('Undecided', 'Undecided'),
            ('Agree', 'Agree'),
            ('Agree Strongly', 'Agree Strongly')]
    
    # 配置每个选项对应的分值,可根据业务需求自行调整
    SCORE_MAP = {
        'Disagree Strongly': 1,
        'Disagree': 2,
        'Undecided': 3,
        'Agree': 4,
        'Agree Strongly': 5
    }
    
    question = models.ForeignKey(Survey_Question, on_delete=models.CASCADE)
    answer_text = models.CharField(max_length=20, choices=CHOICES, default='Undecided')
    date_published = models.DateTimeField('date published', auto_now_add=True)
    created_at = models.DateTimeField('created at', auto_now_add=True)

    # 新增分值属性,直接通过实例.score即可获取对应分值
    @property
    def score(self):
        return self.SCORE_MAP.get(self.answer_text, 0)

    
    def __str__(self):
        return self.answer_text + ' -  ' + self.question.question_text

使用方式

  • 单条数据取值:
# 拿到回答实例后直接取分值
answer = Survey_Answer.objects.get(id=1)
print(answer.answer_text)  # 输出:Agree Strongly
print(answer.score)        # 输出:5
  • 聚合统计(比如计算某道题的平均得分):
from django.db.models import Case, When, IntegerField, Avg

# 统计id=1的问题所有回答的平均分
avg_result = Survey_Answer.objects.filter(question_id=1).aggregate(
    avg_score=Avg(
        Case(
            When(answer_text='Disagree Strongly', then=1),
            When(answer_text='Disagree', then=2),
            When(answer_text='Undecided', then=3),
            When(answer_text='Agree', then=4),
            When(answer_text='Agree Strongly', then=5),
            output_field=IntegerField()
        )
    )
)
print(avg_result['avg_score'])

优势:改完代码重启服务即可生效,不需要执行数据库迁移,已有历史数据完全不受影响,后续调整分值只需要修改SCORE_MAP配置即可。


方案二:直接存储分值(推荐未上线新项目使用)

如果项目还没正式上线、没有存量数据,可以直接调整Choice结构,把分值作为实际存储值存入数据库,查询和统计效率更高。
修改后的模型代码:

class Survey_Answer(models.Model):
    # 元组第一个值为数据库存储的分值,第二个值为前端展示的选项文本
    CHOICES = [
        (1, 'Disagree Strongly'),
        (2, 'Disagree'),
        (3, 'Undecided'),
        (4, 'Agree'),
        (5, 'Agree Strongly')
    ]
    
    question = models.ForeignKey(Survey_Question, on_delete=models.CASCADE)
    # 字段改为IntegerField类型,直接存储分值
    answer = models.IntegerField(choices=CHOICES, default=3)
    date_published = models.DateTimeField('date published', auto_now_add=True)
    created_at = models.DateTimeField('created at', auto_now_add=True)

    @property
    def answer_text(self):
        # 兼容原有获取选项文本的调用习惯
        return self.get_answer_display()

    @property
    def score(self):
        # 直接返回存储的分值即可
        return self.answer

    
    def __str__(self):
        return self.get_answer_display() + ' -  ' + self.question.question_text

注意:该方案需要执行python manage.py makemigrations和python manage.py migrate完成数据库字段变更,如果已有存量数据需要提前做好数据转换,否则会出现数据不兼容问题。


内容的提问来源于stack exchange,提问作者Roronoa_Z

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 15:03:11