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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:37:18