route queryset get_object_or_404 framework detail decorators createapiview create python django api django-rest-framework http-patch

python - queryset - django rest framework serializer



¿Cómo PATCHAR un solo campo usando Django Rest Framework? (4)

Tengo un modelo ''MyModel'' con muchos campos y me gustaría actualizar un ''estado'' de campo usando el método PATCH. Estoy usando vistas basadas en la clase. ¿Hay alguna manera de implementar PATCH?


Como Kevin Brown dijo que puedes usar el partial=True , que chefarov aclaró muy bien.

Solo me gustaría corregirlos y decir que podría usar los genéricos libremente, dependiendo del método HTTP que esté usando:

  • Si está utilizando el método PATCH HTTP como se le pidió, puede sacarlo de la caja. Puede ver el código de UpdateModelMixin para partial_update :

    def partial_update(self, request, *args, **kwargs): kwargs[''partial''] = True return self.update(request, *args, **kwargs)

  • Para cualquier método HTTP diferente de PATCH, esto se puede lograr simplemente anulando el método get_serializer siguiente manera:

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

Esto creará el serializador como parcial, y el resto de los genéricos funcionarán como un hechizo sin ninguna intervención manual en el mecanismo de actualización / partial_update.

Bajo el capó

Utilicé el genérico: generics.UpdateAPIView que usa UpdateModelMixin que tiene este código:

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) …

Por lo tanto, si anula la función get_serializer , puede anular el argumento parcial y forzarlo a ser verdadero.

Tenga en cuenta que si desea que sea parcial solo para algunos de los métodos HTTP, esto hace que este enfoque sea más difícil.

Estoy usando djangorestframework == 3.5.3



Luché con este por un tiempo, pero es una implementación muy sencilla que usa vistas genéricas o una combinación de vistas genéricas y combinaciones.

En el caso de usar una vista de actualización genérica (generics.UpdateAPIView), simplemente use el siguiente código, asegurándose de que el tipo de solicitud sea PATCH:

class UpdateUser(generics.UpdateAPIView): queryset = User.objects.all() serializer_class = UserSerializer

¡No hay nada más que eso!

Si está utilizando una actualización mixin (mixins.UpdateModelMixin) en combinación con una vista genérica (generics.GenericAPIView), use el siguiente código, asegurándose de que el tipo de solicitud sea 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)

El segundo ejemplo es más complejo, muestra cómo anular el campo de búsqueda y búsqueda, pero el código al que debe prestar atención es la función de parche.


Parece que es compatible fuera de la caja. En la API de su navegador, navegue a una página de detalles del modelo, en la parte inferior junto a la pestaña HTML Form haga clic en Raw data , elimine todo de la cadena JSON, excepto el campo de ID y el campo que desea cambiar, y haga clic en PATCH . Se realiza una actualización parcial de PATCH .

Estoy usando djangorestframework==3.2.4 , y no he tenido que hacer nada con mis ViewSets y Serializadores para habilitar esto.

En este ejemplo, estamos actualizando el campo bool status_field del modelo, y estoy usando jquery 2.2.1. Agregue lo siguiente al <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>

Luego en un <form> :

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

Elegí permitir que la casilla de verificación cambie, luego revertirla en caso de falla. Pero puede reemplazar el click con el mousedown para actualizar solo el valor de la casilla de verificación una vez que la llamada AJAX haya tenido éxito. Sin embargo, creo que esto llevará a las personas a hacer clic repetidamente en la casilla de verificación para conexiones lentas.