kakakakakakakk
kakakakakakakk

Reputation: 519

Django create an object that has a reference to another object using serializers

I want to create an order that has multiple ads and each ad must have a reference to a display object. I did this kind of thing previously just by setting the object's id in the put method and it worked well.

models.py

class OrdersDj(models.Model):
    id = models.CharField(primary_key=True, max_length=32, default=generate_uuid)
    user_id =  models.CharField(max_length=45, blank=True, null=True)

    class Meta:
        ordering = ["dateplaced"]

class AdsDj(models.Model):
    id = models.CharField(primary_key=True, max_length=32, default=generate_uuid)
    order = models.ForeignKey(OrdersDj,on_delete=models.CASCADE, blank=False, null=True)
    display = models.ForeignKey(Displays, on_delete=models.CASCADE, blank=False, null=True)
     null=True)

serializers.py

class AdsSerializer(serializers.ModelSerializer):
    
    display = DisplaySerializer()
    
    class Meta:
            model = Ads
            fields = "__all__"
        
class OrderSerializer(serializers.ModelSerializer):
    
    ads = AdsSerializer(source="adsdj_set", many=True)
    
    def create(self, validated_data):
        ads_data = validated_data.pop('adsdj_set')
        order = Orders.objects.create(**validated_data)
        for ad in ads_data:
            Ads.objects.create(order=order, **ad)
        return order

    class Meta:
        model = Orders
        fields = "__all__"

the put method data

{
    "user_id": "1",
    "ads": [
        {
            "display_id": "10",
            // "display" : 10,
            // "display" : "10",
        }
    ]
}

Here in dependence of what I insert for display, it expects a dictionary and not any other types.

{
    "ads": [
        {
            "display": {
                "non_field_errors": [
                    "Invalid data. Expected a dictionary, but got str."
                ]
            }
        }
    ]
}

Upvotes: 0

Views: 982

Answers (1)

Sardar Faisal
Sardar Faisal

Reputation: 671

Hopefully it is been solved.

AdSerializer has a nested DisplaySerializer that is why it expects the input to be display data(all mandatory attributes on the Display model).

By declaring a nested DisplaySerializer you are announcing that it expects data to create Display object and won't be using an existing Display object.

In order to use an existing Display object remove the nested serializer (in this case DisplaySerializer). Or provide the necessary attributes for creation of a display object.

{
    "ads": 
        {
            "order": 1,
            "display": {
                "field1": "value1",
                "field2": "value2"
            }
        }
}

Upvotes: 1

Related Questions