geniuz
geniuz

Reputation: 21

django rest framework model foreign key

I have two models

class Order(models.Model):
     fields...

 class OrderItem(models.Model):
     fiels...
     order = models.ForeignKey(Order, related_name='items')

and I have two serializers:

class CreateOrderItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderItem
        resource_name = 'order-item'
        fields = ('order', 'count')
   .....
class OrderSerializer(serializers.ModelSerializer):
     items = CreateOrderItemSerializer(many=True)
     class Meta:
         model = Order
         resource_name = 'order'
         fields = ('id','items')

I posted order with items array like this:

{
    'ordername': 'foo',
    'items': [{
        'name': 'foo1',
        },{
        'name': 'foo2',
        },
      ]
}

But I have error:

"order":["This field is required."]

how can I first create order later create items with this orderid?

Upvotes: 0

Views: 953

Answers (2)

Serjik
Serjik

Reputation: 10931

There is a good solution here Django Rest Framework writable nested serializers which this is almost the same problem here.

The difference is here ForeignKey is used instead of ManyToMany which will cause required field error

adding extra_kwargs solved this problem, there is another way which is add null=True to foreignkey field

order = models.ForeignKey(Order, related_name='items', null=True)

Upvotes: 0

geniuz
geniuz

Reputation: 21

my own answer to question: first add extra_kwargs to item serializer:

class CreateOrderItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderItem
        resource_name = 'order-item'
        fields = ('order', 'count')
        extra_kwargs = {
            'order': {'required': False},
        }

after add create method to orderserializer:

def create(self, validated_data):
    items_data = validated_data.pop('items')
    order = Order.objects.create(**validated_data)
    for item in items_data:
        item_name = item['name']
        item, created = OrderItem.objects.get_or_create(order=order,name=item_name)
    return order

Upvotes: 2

Related Questions