Issue
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.
Solution
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)
Answered By - Felix Eklöf
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.