Подтвердить что ты не робот

Как очистить одно поле с помощью Django Rest Framework?

У меня есть модель "MyModel" со ​​многими полями, и я хотел бы обновить поле "статус" с помощью метода PATCH. Я использую представления на основе классов. Есть ли способ реализовать PATCH?

4b9b3361

Ответ 1

Сериализаторы разрешают частичные обновления, указав partial=True при инициализации serialzer. Вот как PATCH запросы обрабатываются по умолчанию в общих представлениях.

serializer = CommentSerializer(comment, data=request.data, partial=True)

Это позволит вам обновлять отдельные поля в сериализаторе или все поля, если вы хотите, без каких-либо ограничений стандартного запроса PUT.

Ответ 2

Как Кевин Браун заявил, что вы можете использовать partial=True, который chefarov прояснил красиво.

Я просто хотел бы исправить их и сказать, что вы можете использовать generics свободно, в зависимости от используемого вами метода HTTP:

  • Если вы используете HTTP-метод PATCH, как заданный, вы получаете его из коробки. Вы можете увидеть UpdateModelMixin код для partial_update:

    def partial_update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)
    
  • Для любого метода HTTP, отличного от PATCH, это можно выполнить, просто переопределив метод get_serializer следующим образом:

    def get_serializer(self, *args, **kwargs):
        kwargs['partial'] = True
        return super(YOUR_CLASS, self).get_serializer(*args, **kwargs)
    

Это создаст сериализатор как частичный, а остальные генераторы будут работать как шарм без ручного вмешательства в механизм update/partial_update.

Под капотом

Я использовал общий: generics.UpdateAPIView, который использует UpdateModelMixin, который имеет этот код:

def update(self, request, *args, **kwargs):
    partial = kwargs.pop('partial', False)
    instance = self.get_object()
    serializer = self.get_serializer(instance, data=request.data, partial=partial)
    …

Итак, если вы переопределите функцию get_serializer, вы можете фактически переопределить частичный аргумент и заставить его быть истинным.

Обратите внимание, что если вы хотите, чтобы он был частичным только для некоторых методов HTTP, это затрудняет этот подход.

Я использую djangorestframework == 3.5.3

Ответ 3

Кажется, он поддерживается из коробки. В браузере API перейдите на страницу описания модели, внизу рядом с вкладкой HTML Form нажмите Raw data, удалите все из строки JSON, кроме поля ID и поля, которое вы хотите изменить, и нажмите PATCH, Выполняется частичное обновление PATCH.

Я использую djangorestframework==3.2.4, и мне не нужно было ничего делать с моими представлениями и сериализаторами, чтобы включить это.

В этом примере мы обновляем поле bool status_field модели, и я использую jquery 2.2.1. Добавьте в <head> следующее:

<script src="{% static 'my_app/jquery.min.js' %}"></script>
<script>
$(document).ready(function(){
    var chk_status_field = $('#status_field');
    chk_status_field.click(function(){
        $.ajax({url: "{% url 'model-detail' your_rendering_context.id %}",
            type: 'PATCH', timeout: 3000, data: { status_field: this.checked }
        })
        .fail(function(){
            alert('Error updating this model instance.');
            chk_status_field.prop('checked', !chk_status_field.prop('checked'));
        });
    });
});
</script>

Тогда в <form>:

<input type="checkbox" id="status_field" {% if your_rendering_context.status_field %} 
    checked {% endif %} >

Я решил разрешить изменение флажка, а затем вернуть его в случае сбоя. Но вы можете заменить click на mousedown, чтобы обновить значение флажка только после того, как вызов AJAX преуспел. Я думаю, что это приведет к тому, что люди будут многократно нажимать флажок для медленных соединений.

Ответ 4

Я некоторое время боролся с этим, но это очень простая реализация, использующая общие представления или комбинацию общих представлений и миксинов.

В случае использования общего представления обновления (generics.UpdateAPIView) просто используйте следующий код, убедившись, что тип запроса - PATCH:

class UpdateUser(generics.UpdateAPIView):

    queryset = User.objects.all()
    serializer_class = UserSerializer

Нет ничего другого!

Если вы используете обновление mixin (mixins.UpdateModelMixin) в сочетании с общим представлением (generics.GenericAPIView), используйте следующий код, удостоверяясь, что тип запроса - PATCH:

class ActivateUser(mixins.UpdateModelMixin, generics.GenericAPIView):

serializer_class = UserSerializer
model = User
lookup_field = 'email'

def get_queryset(self):
    queryset = self.model.objects.filter(active=False)
    return queryset

def patch(self, request, *args, **kwargs):
    return self.partial_update(request, *args, **kwargs)

Второй пример более сложный, показывая вам, как переопределить поле запроса и поиска, но код, на который вы должны обратить внимание, - это функция патча.