获取 NOT NULL 约束失败:DRF 中的 locations_location.city_id
Getting NOT NULL constraint failed: locations_location.city_id in DRF
当我尝试在 api 中通过 DRF 序列器创建对象时,出现错误 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.
访问
首先,你在 LocationSerializer
中的 create
方法中有 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)
当我尝试在 api 中通过 DRF 序列器创建对象时,出现错误 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.
访问首先,你在 LocationSerializer
中的 create
方法中有 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)