如何在Django数据库中存储键值对?以学生成绩记录为例
实现学生成绩字段的几种方案
针对你要在Django的StudentRecord模型中添加类似字典的成绩字段需求,有以下几种实用方案:
1. 使用JSONField(推荐,简单高效)
Django 3.1及以上版本原生支持JSONField,可以直接存储字典、列表等结构化数据,非常适配你的场景。注意要给CharField补充max_length参数(Django要求必填):
from django.db import models class StudentRecord(models.Model): studentname = models.CharField(max_length=100) marks = models.JSONField(default=dict) # 默认值设为空字典
使用示例
# 创建学生记录 student = StudentRecord.objects.create( studentname="Darshan Bhat", marks={"Science":98, "Maths":99, "Computer":95} ) # 读取成绩 print(student.marks["Science"]) # 输出 98
这种方案优势是代码简洁,无需额外模型,适合成绩科目不固定、不需要对单个科目成绩做复杂数据库查询的场景。
2. 创建关联模型(规范化设计,适合复杂查询)
如果后续需要按科目统计成绩、查询某科最高分等操作,推荐使用数据库规范化设计,单独创建成绩模型并与学生模型关联:
from django.db import models class StudentRecord(models.Model): studentname = models.CharField(max_length=100) class Mark(models.Model): student = models.ForeignKey( StudentRecord, on_delete=models.CASCADE, related_name="marks" # 方便通过学生实例反向查询成绩 ) subject = models.CharField(max_length=50) score = models.IntegerField()
使用示例
# 创建学生及对应成绩 student = StudentRecord.objects.create(studentname="Darshan Bhat") Mark.objects.create(student=student, subject="Science", score=98) Mark.objects.create(student=student, subject="Maths", score=99) # 查询学生所有成绩 for mark in student.marks.all(): print(f"{mark.subject}: {mark.score}") # 查询Science科目所有学生的成绩 science_marks = Mark.objects.filter(subject="Science")
这种方案适合需要对成绩进行复杂业务操作的场景,符合数据库设计的三范式,避免数据冗余。
3. ArrayField(仅PostgreSQL支持)
如果你使用PostgreSQL数据库,可以用ArrayField存储元组列表,但需要手动处理数据类型转换,灵活性不如JSONField:
from django.db import models from django.contrib.postgres.fields import ArrayField class StudentRecord(models.Model): studentname = models.CharField(max_length=100) marks = ArrayField( models.CharField(max_length=50), default=list )
使用示例
# 存储成绩(需转成字符串元组) student = StudentRecord.objects.create( studentname="Darshan Bhat", marks=[("Science", "98"), ("Maths", "99")] ) # 读取时需要自行转换类型 science_score = int(student.marks[0][1])
内容的提问来源于stack exchange,提问作者Darshan Bhat
相关产品推荐
相关产品推荐

