Вызов обновления сериализатора в функции в django

У меня есть эта дата, приходящая с фронтенда:

d = {'dispatch_date': '2021-08-25T10:40:19.783Z', 'send_from_warehouse': 2, 'sales_order': 635, 
'flows': [{'flow': 67, 'kit': 8, 'asked_quantity': 9, 'alloted_quantity': '9'}, 
          {'flow': 67, 'kit': 3, 'asked_quantity': 8, 'alloted_quantity': '0'}, 
          {'flow': 67, 'kit': 49, 'asked_quantity': 7, 'alloted_quantity': '0'}], 
    'model': 'Rent', 'vehicle_type': 'Part Load', 
    'transport_by': 4, 'expected_delivery': '2021-08-25T10:40:19.783Z', 
    'owner': 2, 'transaction_no': 2807}

используя эти данные, я хочу отредактировать объект Material Request с id 635.

Как вызвать редактирование из сериализатора запроса материала?

class MaterialRequestFlowSerializer(serializers.ModelSerializer):

    class Meta:
        model = MaterialRequestFlow
        fields = "__all__"


class MaterialRequestSerializer(serializers.ModelSerializer):

    flows = MaterialRequestFlowSerializer(many=True)

    class Meta:
        model = MaterialRequest
        fields = "__all__"


    def create(self, validated_data):
        print("validated", validated_data)
        items_objects = validated_data.pop('flows', None)
        prdcts = []
        for item in items_objects:
            i = MaterialRequestFlow.objects.create(**item)
            prdcts.append(i)
        instance = MaterialRequest.objects.create(**validated_data)
        print("prdcts", prdcts)
        instance.flows.set(prdcts)
        return instance

    def update(self, instance, validated_data):
        print("s")
        items_objects = validated_data.pop('flows',None)
        prdcts = []
        for item in items_objects:
            print("item", item)
            fk_instance, created = MaterialRequestFlow.objects.update_or_create(pk=item.get('id'), defaults=item)
            prdcts.append(fk_instance.pk)
        instance.flows.set(prdcts)
        instance = super(MaterialRequestSerializer, self).update(instance, validated_data)
        return instance

Ваш сервер должен вернуть идентификатор ресурса, после чего обновление можно выполнить с помощью:

Виды

class MaterialRequestUpdateView(UpdateAPIView):
    serializer_class = MaterialRequestSerializer
    query_set = MaterialRequest.objects.all() # Or filter the queryset
    permission_classes = [AllowAny] # Or any other permission class

Урлы

urlpatterns += [
    path('material-requests/<int:id>/update/', MaterialRequestUpdateView.as_view(), name='material-request-update'),
]

Теперь вы можете сделать запрос следующим образом:

host/material-requests/635/update/

Я бы предложил вам использовать поле UUID вместо первичного ключа для поиска по соображениям безопасности, как показано ниже:

модели

class MaterialRequest(models.Model):
    uuid = models.UUIDField(default=uuid4, unique=True, db_index=True)
    # Other fields

Виды

class MaterialRequestUpdateView(UpdateAPIView):
    serializer_class = MaterialRequestSerializer
    lookup_field = 'uuid'
    lookup_url_kwarg = 'uuid'
    query_set = MaterialRequest.objects.all() # Or filter the queryset
    permission_classes = [AllowAny] # Or any other permission class

Урлы

urlpatterns += [
    path('material-requests/<uuid:uuid>/update/', MaterialRequestUpdateView.as_view(), name='material-request-update'),
]

Также обновите свойства queryset и permission_classes в MaterialRequestUpdateView, потому что сейчас каждый пользователь может обновить каждый экземпляр MaterialRequest

Для ручного использования сериализатора

material_request = MaterialRequest.objects.get(id=635)
serializer = MaterialRequestSerializer(instance=material_request, data={}) # Inserts the updated data into data dict, use partial=True for a partial update
serializer.is_valid(raise_exception=True)
serializer.save()
Вернуться на верх