I send the following JSON:

{"delivery":{"delivery_time":"2016-05-31T12:18:47Z","delivery_adress":"123","phone":"123"},"paymentMethod":{"id":"1","title":"123124123"},"summ":"23","success":false} 

Serializer:

 class OrderSerializer(serializers.ModelSerializer): delivery = DeliverySerializer(required=False, allow_null=True) paymentMethod = PaymentsSerializer(required=False, allow_null=True) class Meta: model = Order fields = ( 'delivery', 'paymentMethod','summ','success') #'id', def create(self, validated_data): deliverys_data = validated_data.pop('delivery') delivery = Delivery.objects.create(**deliverys_data) paymentsMethod_data = validated_data.pop('paymentMethod') data=list(paymentsMethod_data.values())[:3] print(data) payment_method = Payments.objects.create(**paymentsMethod_data) order = Order.objects.create(delivery=delivery,paymentMethod=payment_method,**validated_data) return order 

I try to get an id so that I can use it in Object ordere using Object get, and not create a new one every time, but each time I get only: [u'123124123 '], given only by name. At the moment, the order is created but each time creating new methods of payment

And I do not understand where he goes

View

 @api_view(['POST']) def order_post(request, format=None): if request.method == 'POST': serializer = OrderSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

Other serializers

 class DeliverySerializer(serializers.ModelSerializer): class Meta: model = Delivery fields = ('delivery_time','delivery_adress','phone')#'id', def create(self, validated_data): return Delivery.objects.create(**validated_data) class PaymentsSerializer(serializers.ModelSerializer): class Meta: model = Payments fields = ('id','title') # def create(self, validated_data): return Payments.objects.create(**validated_data) 

    2 answers 2

    When you pass information about a payment method, the serializer ignores the id field β€” it is read-only. And since the instance argument is not passed to the serializer, it creates a new payment method using the create method.

    If you do not need to change the payment method, paymentMethod = PaymentsSerializer(required=False, allow_null=True) must be removed. Then the field will only accept the id of the existing payment methods. The request will be as follows:

     { "delivery": { "delivery_time":"2016-05-31T12:18:47Z", "delivery_adress":"123", "phone":"123" }, "paymentMethod": "1", "summ":"23", "success":false } 

    But the answer will also return the id. If you need a different behavior, you will need the logic of OrderSerializer or PaymentsSerializer.

    • Returns BadRequest - Weit
    • What does the response body return? - Chikiro
    • "Invalid data. Expected a dictionary, but got list." - Weit
    • See if your dictionary {...} is wrapped in a list [...]. - Chikiro
    • {"delivery": {"delivery_time": "2016-05-31T12: 18: 47Z", "delivery_adress": "123", "phone": "123"}, "paymentMethod": "1", "summ" : "23", "success": false} I’m sending this request, everything looks fine - Weit

    For such cases, several serializers are created, usually three:

    • list serializer that contains only the minimum required number of fields
    • serializer for a detailed view of the record
    • record creation / update serializer

    If you follow this logic, then you should have something like this code (in general):

    app.serializers.py

     from rest_framework.serializers import ModelSerializer from rest_framework.serializers import PrimaryKeyRelatedField from .models import ModelClass from anothermodel.models import AnotherModel # Бвязанная модСль from anothermodel.serializers import AnotherModelListSerializer class ModelListSerializer(ModelSerializer): """ Π‘Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ для списка. Как ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, Π² списках Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ±Ρ‰ΠΈΠ΅ свойства ΠΌΠΎΠ΄Π΅Π»ΠΈ, Π° внСшниС ΠΊΠ»ΡŽΡ‡ΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈ вовсС ΡΠΏΡ€ΡΡ‚Π°Ρ‚ΡŒ """ class Meta: model = ModelClass exclude = [ "related_model" ] # Π’Π½Π΅ΡˆΠ½ΠΈΠΉ ΠΊΠ»ΡŽΡ‡, сСйчас Π΅Π³ΠΎ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ class ModelDetailSerializer(ModelSerializer): """ Π‘Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ для Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ записи. ПолС related_field Π±ΡƒΠ΄Π΅Ρ‚ сСриализовано, ΠΈ Π½Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅ ΠΌΡ‹ ΡƒΠ²ΠΈΠ΄ΠΈΠΌ JSON-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌΠΈ полями. """ related_model = AnotherModelListSerializer() class Meta: model = ModelClass class ModelWriteSerializer(ModelSerializer): """ Π‘Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ для создания/обновлСния ΠΌΠΎΠ΄Π΅Π»ΠΈ. Π‘ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ id для ΠΌΠΎΠ΄Π΅Π»ΠΈ, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π±ΡƒΠ΄Π΅Ρ‚ связано ΠΏΠΎΠ»Π΅ related_field. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ queryset ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π°Π±ΠΎΡ€ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ связь. """ related_model = PrimaryKeyRelatedField( queryset=AnotherModel.objects.all(), write_only=True ) class Meta: model = ModelClass 

    Now somewhere in the description of the form:

    api.movelviews

     from app.models import ModelClass from rest_framework.viewsets import ModelViewSet from app.serialziers import ModelListSerializer, ModelDetailSerializer, ModelWriteSerializer class ModelClassViewSet(ModelViewSet): queryset = ModelClass.objects.all() # Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΈ get_queryset ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ def get_serializer_class(self): if self.request.method == "GET": if self.action == "list": return ModelListSerializer # GET: /api/models/ return ModelDetailSerializer # GET: /api/models/:id/ return ModelWriteSerializer # POST, PUT, etc ΠΊ /api/models/ ΠΈ /api/models/:id/ class Meta: model = ModelClass 
    • Thanks, interesting, now I will try to implement in practice - Weit
    • But I have a slightly different task. I send 1 JSON to the server and I want to write it to different models - Weit
    • Delivery.objects.create () works as a forced creation of a model and storing it in the database. Read more here: docs.djangoproject.com/en/dev/ref/models/querysets/… - Dunaevsky Maxim
    • In other words, each time calling your serializer will create a new entry. Instead, you should use the function get_or_create - if there is no record in the database, Django will automatically create it: docs.djangoproject.com/en/1.9/ref/models/querysets/… - Dunaevsky Maxim