【问题标题】:Getting NOT NULL constraint failed: locations_location.city_id in DRF获取 NOT NULL 约束失败:DRF 中的locations_location.city_id
【发布时间】:2021-12-17 17:22:24
【问题描述】:

当我尝试在我的 api 中通过 DRF serailizers 创建对象时,我收到错误 NOT NULL constraint failed: locations_location.city_id

我查看了类似的here,提供的解决方案似乎正是我必须开始的。

我的模型:

class City(models.Model):
    code = models.CharField(max_length=4, default="", blank=False, unique=True)
    name = models.CharField(max_length=40, default="", blank=False, unique=True)
    time_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.name}, ({self.code})"

    class Meta:
        verbose_name = "City"
        verbose_name_plural = "Cities"


class Location(models.Model):
    status_choice = (
        ("Available", "Available"),
        ("Unavailable", "Unavailable"),
        ("Active", "Active"),
    )
    city = models.ForeignKey(City, on_delete=models.CASCADE, related_name="locations")
    name = models.CharField(max_length=256, default="", blank=True)
    rent = models.DecimalField(max_digits=7, decimal_places=2)
    email = models.EmailField(max_length=64)
    phone = models.CharField(max_length=20, default="", blank=True)
    lon = models.DecimalField(max_digits=7, decimal_places=5, blank=True, null=True)
    lat = models.DecimalField(max_digits=7, decimal_places=5, blank=True, null=True)
    street_number = models.CharField(max_length=50, null=True)
    street_name = models.CharField(max_length=50, null=True)
    postal_code = models.CharField(max_length=50, null=True)
    status = models.CharField(max_length=50, choices=status_choice, default="Available")
    time_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.name} {self.status}"

我的助推器:


class CitySerializer(serializers.ModelSerializer):
    locations = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = City
        fields = "__all__"

    def create(self, validated_data):
        return City.objects.create(**validated_data)


class LocationSerializer(serializers.ModelSerializer):
    location_events = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
    booked_days = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = Location
        fields = "__all__"
        depth = 1

    def create(self, validated_data):
        city = serializers.PrimaryKeyRelatedField(  # noqa
            many=False, queryset=City.objects.all()
        )
        return Location.objects.create(**validated_data)

这是在 POST 请求中传递给 api 的虚假测试数据:

{
 "name": "Darmstadt Hotel", 
 "city": 1,
 "email": "fischernicolai@nohlmans.de", 
 "phone": "+49(0)7219 993238", 
 "rent": 275.38, 
 "lat": 52.9427, 
 "lon": 12.1076, 
 "street_name": "Eimerstra\\u00dfe", 
 "street_number": "34", 
 "postal_code": "80843", 
 "status": "Available"
}

数据库中存在一个id为1的城市,可以通过api访问。

【问题讨论】:

    标签: python django api serialization django-rest-framework


    【解决方案1】:

    首先,create 方法中的 LocationSerializer 中有 city 字段,这一定是错误吗?它应该是booked_days = ... 下面的行。 不过我不确定这是否能解决问题。

    class LocationSerializer(serializers.ModelSerializer):
        location_events = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
        booked_days = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
        city = serializers.PrimaryKeyRelatedField(  # noqa
            many=False, queryset=City.objects.all()
        ) # Move it here
    
        class Meta:
            model = Location
            fields = "__all__"
            depth = 1
    
        def create(self, validated_data):
            return Location.objects.create(**validated_data)
    

    【讨论】:

    • 成功了!我一直在寻找一个星期的解决方案。我没有注意到其他人的主键相关字段在哪里。谢谢。
    猜你喜欢
    • 2021-01-31
    • 2015-04-22
    • 2019-03-02
    • 2018-08-24
    • 2022-01-19
    • 2021-11-16
    • 2020-12-18
    • 2021-03-20
    • 2020-02-11
    相关资源
    最近更新 更多