¿Cómo PATCHAR un solo campo utilizando Django Rest Framework?

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?

Los serializadores permiten actualizaciones parciales especificando partial=True al inicializar el serialzer. Así es como las solicitudes de PATCH se manejan de forma predeterminada en las vistas genéricas .

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

Esto le permitirá actualizar campos individuales en un serializador, o todos los campos si lo desea, sin ninguna de las restricciones de una solicitud PUT estándar.

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 generics 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 rest de los generics 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

Parece que es compatible fuera de la caja. En la API de su navegador, navegue a la 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 :

   

Luego en un

:

  

Elegí permitir que la checkbox cambie, luego revertirla en caso de falla. Pero puede reemplazar el click con el mousedown para actualizar solo el valor de la checkbox una vez que la llamada AJAX haya tenido éxito. Sin embargo, creo que esto hará que la gente haga clic repetidamente en la checkbox para conexiones lentas.

Si alguien todavía está planeando encontrar una solución simple utilizando ModelSerializer sin cambiar gran parte de sus vistas, puede ModelSerializer subclase de ModelSerializer y hacer que todo su ModelSerializer s herede.

 class PatchModelSerializer(serializers.ModelSerializer): def __init__(self, *args, **kwargs): kwargs['partial'] = True super(PatchModelSerializer, self).__init__(*args, **kwargs) class ArticleSerializer(PatchModelSerializer): class Meta: model = Article 

Luché con este por un tiempo, pero es una implementación muy sencilla que utiliza vistas genéricas o una combinación de vistas genéricas y combinaciones de 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.