Django一对多关系:基于双复合键生成唯一行的实现
解决方案
1. 模型层定义复合键关系
Django ORM不直接支持复合主键,但可以通过唯一约束实现复合键的效果。针对你的三张表,正确的模型定义如下:
from django.db import models from django.contrib.auth.models import User class Parish(models.Model): author = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='parishes') # 补充你的其他业务字段 class Checklist(models.Model): str_status = models.CharField(max_length=255) # 补充检查项的其他固定字段 class All_Inspection(models.Model): parish = models.ForeignKey(Parish, on_delete=models.CASCADE) checklist = models.ForeignKey(Checklist, on_delete=models.CASCADE) str_comment = models.TextField(blank=True) class Meta: # 定义复合唯一约束,确保一个Parish对应一个Checklist仅存在一条记录 constraints = [ models.UniqueConstraint(fields=['parish', 'checklist'], name='unique_parish_checklist') ]
2. 修正视图代码中的问题
你的现有代码存在逻辑错误,同时未处理重复生成记录的情况,修正后的代码如下:
def form_valid(self, form): # 关联当前用户为Parish的作者 form.instance.author = self.request.user # 保存Parish记录 parish = form.save() # 获取所有预定义的Checklist记录 checklists = Checklist.objects.all() # 批量生成或复用All_Inspection记录 for checklist in checklists: # get_or_create会自动判断:组合已存在则返回现有记录,不存在则新建 All_Inspection.objects.get_or_create( parish=parish, checklist=checklist, defaults={'str_comment': ''} ) return super().form_valid(form)
3. 解决Checklist ID递增的问题
Checklist的ID递增是数据库自增主键的默认行为,属于正常现象。如果你的需求是固定检查项不新增,只需预先在Checklist表中录入所有需要的检查项,后续避免在其他逻辑中创建新的Checklist记录即可。
若担心重复生成All_Inspection记录,上述代码中的get_or_create方法会自动过滤重复组合,不会重复创建记录。
内容的提问来源于stack exchange,提问作者Dev_Frameworks
相关产品推荐
相关产品推荐

