When I try to create an object through DRF serailizers in my api, I get the error NOT NULL constraint failed: locations_location.city_id
.
I looked at a similar here and the solution provided seems to be exactly what I had to begin with.
My models:
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}"
My serailizers:
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)
This is the fake test data passed to the api in POST request:
{
"name": "Darmstadt Hotel",
"city": 1,
"email": "[email protected]",
"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"
}
A city with id of 1 exists in the database and is accessible through the api.
CodePudding user response:
Firstly, you have the city field in your LocationSerializer
inside the create
method, that must be an error? It should be the line below booked_days = ...
.
I'm not sure this will solve the problem however.
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)