【问题标题】:django.db.utils.IntegrityError: NOT NULL constraint failed fom Postmandjango.db.utils.IntegrityError: NOT NULL 约束失败来自 Postman
【发布时间】:2021-01-15 22:42:37
【问题描述】:

我正在尝试使用 Django rest 框架创建一个带有外键的简单模型。 这是模型:

class Route(models.Model):
    place_origin = models.ForeignKey(
    Place, null=False, on_delete=models.DO_NOTHING)

class Place(models.Model):
    name = models.CharField(max_length=50, null=False)

这是每个模型的序列化程序:

class PlaceSerializer(serializers.ModelSerializer):

    class Meta:
        model = Place
        fields = ["id", "name"]

class RouteSerializer(serializers.ModelSerializer):

    place_origin = PlaceSerializer(many=False, read_only=True)
    class Meta:
        model = Route
        fields = ["id", "place_origin"]

此 RouteSerializer 具有 place_origin 属性,以便在我查看路线详细信息时显示地点详细信息(其中的所有字段)。我的意思是我想显示的路线:

[
    {
    "id": 1,
    "place_origin": {
        "id": 1,
        "name": "New york"
        }
    },
   {
    "id": 2,
    "place_origin": {
        "id": 2,
        "name": "Boston"
        }
    }
]

不仅仅是:

[
    {
    "id": 1,
    "place_origin": 1
    },
   {
    "id": 2,
    "place_origin": 2
    }
]

这是视图:

@api_view(['POST'])
def routes_new_route_view(request):
    """
    Create a new route
    """
    if request.method == "POST":
        data = JSONParser().parse(request)
        place_origin = Place.objects.get(id=data["place_origin"])
        data["place_origin"] = PlaceSerializer(place_origin)
        data["place_origin"] = data["place_origin"].data
        serializer = RouteSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=201)
        else:

        return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

我想这样发送邮递员的请求:

{
    "place_origin": 3
}

但是我从标题中得到了错误。 感谢大家的帮助!

【问题讨论】:

    标签: python django rest frameworks postman


    【解决方案1】:

    错误是您尝试通过 PlaceSerializer 发送数据,但该字段是只读的。另一方面,您的数据库需要 place_origin ,因为您在模型中精确了 null=False 。两者结合给出错误“非空约束失败”。

    最简单的方法是稍微修改您的序列化程序,以便让一个字段用于写入,另一个用于读取。

    class RouteSerializer(serializers.ModelSerializer):
    
        place_origin = PlaceSerializer(many=False, read_only=True)
        place = serializers.PrimaryKeyRelatedField(source="place_origin",queryset=Place.objects.all(),write_only=True)
        class Meta:
            model = Route
            fields = ["id", "place_origin", "place"]
    
    

    在这里,您将使用 place 字段作为创建与您的 Route 实例的关系的一种方式。

    【讨论】:

    • 我也必须将该字段添加到模型中?
    • 不,source 参数告诉序列化程序要搜索的字段。所以它看起来在发送 {"place":1} 时与 place_origin 建立关系。更新了我的答案,更准确地说明了错误的来源。
    猜你喜欢
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-31
    • 2016-04-07
    • 2015-04-22
    相关资源
    最近更新 更多