Markus
Markus

Reputation: 469

Django KeyError after returning instance (Serializer)

im facing following problem: Im inserting a Cantonment (Household) into my database with an address and a accomodation (Sofa/Bed ...). Everything works fine (inserting) but after everything is correctly inserted the returned instance of the created object (cantonment) is throwing an error:

Got AttributeError when attempting to get a value for field accomodations on serializer CantonmentCreateSerializer. The serializer field might be named incorrectly and not match any attribute or key on the Cantonment instance. Original exception text was: 'Cantonment' object has no attribute 'accomodations'.

The query used is in this example ( Query used ).

As i said insert is working, but returning the instance is throwing an error. Adding source='accomodation_set' would probably work for showing the correct output, but then i cannot insert any data.

Is there a way i can use a different serializer for returning an instance (which is created). If you need more information ( models ) tell me :)

Appreciate your help

class CantonmentCreateSerializer(serializers.ModelSerializer):
    address = AddressSerializer()
    accomodations = AccomodationSerializer(many=True)

    # other profile
    class Meta:
        model = Cantonment
        fields = ('id','user','name', 'description', 'type', 'stay_type', 'geom', 'address', 'accomodations')
        read_only_fields=('id', 'user',)

    def create(self, validated_data):
        with transaction.atomic():
            # Create Cantonment first and link it to the address and all accomodations

            ''' Query used
            {
                "stay_type": 1,
                "address": {
                    "raw_address": "1",
                    "street_number": "2",
                    "route": "3",
                    "city": "4",
                    "postal_code": "5",
                    "state": "6",
                    "state_code": "7",
                    "country": "8",
                    "country_code": "9"
                },
                "type": 1,
                "accomodations": [
                    {"accomodation_option": "2", "available_space": "3"},
                    {"accomodation_option": "4", "available_space": "4"}
                ],
                "description": "test",
                "geom": "POINT(1 2)",
                "name": "123"
            }
            '''

            accomodations_data = validated_data.pop('accomodations')
            address_data = validated_data.pop('address')

            cantonment = Cantonment.objects.create(user = validated_data.get('user'),
                name = validated_data.get('name'),
                description = validated_data.get('description'),
                type = validated_data.get('type'),
                stay_type = validated_data.get('stay_type'),
                geom = validated_data.get('geom'))


            address = Address.objects.create(cantonment = cantonment, **address_data)

            # Run through all accomodations submitted and create one accomodation respective
            for accomodation_data in accomodations_data:
               accomodation = Accomodation.objects.create(cantonment = cantonment, **accomodation_data)

        return cantonment

Upvotes: 0

Views: 972

Answers (1)

origamic
origamic

Reputation: 1116

Address and Accomodations must be write only. Because Cantonment Model have no address and accomodations attribute.

class Meta:
    model = Cantonment
    fields = ('id','user','name', 'description', 'type', 'stay_type', 'geom', 'address', 'accomodations')
    read_only_fields=('id', 'user',)
    extra_kwargs = {'address': {'write_only': True}, 'accomodations': {'write_only': True}}

Upvotes: 2

Related Questions