#Problems POSTing an object with a serialiser with nested objects

5 messages · Page 1 of 1 (latest)

misty orchid
#

I've got a problem trying to POST data to an object ilke this:

Models

A place that is in a city.

class City(models.Model):
  name = models.Charfield(max_length=50)

class Place(models.Model):
  name = models.Charfield(max_length=50)
  city = models.ForeignKey(City)

Serializers

I use a nested serializer to get the city within a place, so that i dont have to make 2 api calls whenever i want to display "{place,name} in {city.name}"

class CitySerializer(ModelSerializer):
  class Meta:
    model = City
    fields = '__all__'

class PlaceSerializer(ModelSerializer):
  city = CitySerializer(read_only=True)
  class Meta:
    model = Place
    fields = '__all__'

Views

I just use modelviewsets

class CityViewSet(ReadOnlyModelViewSet):
    queryset = models.City.objects.all()
    serializer_class = serial.CitySerializer

class PlaceViewSet(ReadOnlyModelViewSet):
    queryset = models.Place.objects.all()
    serializer_class = serial.PlaceSerializer

However, I only care about this extra info when I list or retrieve from the API. I'm not interested in creating a place and a scity at the same time.

However, when i try to POST a Place (using the API GUI), it always throws an error that city_id is missing.

This is the POST request contents:

{
"name": "new place",
"city": 1
}
IntegrityError at /API/place/

NOT NULL constraint failed: form_place.city_id

Seeing this error i tried using city_id instead of city but that also didn't work.

{
"name": "new place",
"city_id": 1
}

What is happening, and how could I fix it so that I can both:

  • Get the nested data from list or retrieve operations
  • POST models to the API using the plain fields (without nested stuff)
    ?

I thought maybe I could change the viewset classes so that they use a nested serializer for list and retrieve, and a plan serializer for the other operations, but maybe there's a better solution.

wide flower
#

the read_only=True is likely a problem here, you can't have that for a serializer used to create an instance. at least not if the associated model field must have a value

#

btw I very much recommend you drop the __all__ and replace it with a list of fields each. this will come to bite you sooner than later, especially with nested serializers. it helps a lot regarding longterm maintenance to write these things out

heavy elm
#

As far as I understood root reason os that you have ForeignKey field which always forces you to pass value of instance of such FK model when you try to create child object

#

So it's not about optinal field issue, it's about models dependency