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

Django创建LeadFacilityAssign时触发assigned_facilities_id非空约束错误

错误原因及修复方案

核心错误原因

  1. 循环取值逻辑错误:在create方法的循环中,错误地使用整个assigned_facilities列表调用get()方法,而非循环中的单个facility字典。列表没有get()方法,导致返回None,最终向LeadFacilityAssign传入空值,触发非空约束错误。
  2. 请求字段与序列化器字段不匹配:请求JSON使用键名facilities,但序列化器中定义的字段是assigned_facilities,导致无法正确解析设施数据(若前端未修正,validated_data.pop("assigned_facilities")会得到None,后续逻辑必然出错)。

额外潜在问题

  • Lead模型缺少agent字段:视图中serializer.save(agent=self.request.user)传入了agent参数,但Lead模型未定义该字段,会导致Lead创建失败。
  • facility_id类型不匹配:请求中facility_id是字符串"1",而ForeignKey关联的是整数类型的ID,可能引发类型错误。

修复步骤

1. 修正序列化器的create方法

将循环内的取值对象改为当前循环的facility字典,并转换facility_id为整数:

def create(self, validated_data):
    # 若前端传的是facilities,这里要改为validated_data.pop("facilities")
    assigned_facilities = validated_data.pop("assigned_facilities")
    instance = Lead.objects.create(**validated_data)
    for facility in assigned_facilities:
        # 使用当前循环的facility字典,而非整个列表
        facility_id = int(facility.get('facility_id'))
        datetime_val = facility.get("datetime")
        instance.leadfacility.create(assigned_facilities_id=facility_id, datetime=datetime_val)
    return instance

2. 统一请求字段与序列化器字段

二选一即可:

  • 修改请求JSON的键名为assigned_facilities:
{"assigned_facilities": [{"facility_id": "1","datetime": "2018-12-19 09:26:03.478039"},{"facility_id": "1","datetime": "2018-12-19 09:26:03.478039"}]}
  • 或修改序列化器的字段名为facilities:
class LeadUpdateSerializer(serializers.ModelSerializer):
    is_owner = serializers.SerializerMethodField()
    facilities = serializers.JSONField(required=False, allow_null=True, write_only=True)

    class Meta:
        model = Lead
        fields = ("id","first_name","last_name","is_owner","facilities",)
        read_only_fields = ("id", "is_owner")

    def create(self, validated_data):
        assigned_facilities = validated_data.pop("facilities")
        # 后续逻辑不变
        instance = Lead.objects.create(**validated_data)
        for facility in assigned_facilities:
            facility_id = int(facility.get('facility_id'))
            datetime_val = facility.get("datetime")
            instance.leadfacility.create(assigned_facilities_id=facility_id, datetime=datetime_val)
        return instance

3. 给Lead模型添加agent字段

from django.contrib.auth.models import User

class Lead(models.Model):
    first_name = models.CharField(max_length=40, null=True, blank=True)
    last_name = models.CharField(max_length=40, null=True, blank=True)
    agent = models.ForeignKey(User, on_delete=models.CASCADE, related_name='leads')  # 添加该字段

    def __str__(self):
        return f"{self.first_name} {self.last_name}"

4. 可选:添加Facility存在性校验

避免传入不存在的facility_id导致错误:

from django.core.exceptions import ObjectDoesNotExist

# 在循环内添加校验
try:
    facility = Facility.objects.get(id=facility_id)
    instance.leadfacility.create(assigned_facilities=facility, datetime=datetime_val)
except ObjectDoesNotExist:
    # 可选择抛出异常、跳过该条目或记录日志
    continue

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:40:31