es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

La solicitud de parche React Axios arroja un error 401 aunque se proporciona autorización.

Estás intentando agregar un usuario a un grupo con una solicitud de parche axios. Los datos son correctos pero obtengo un error 401 aunque incluya la autorización en el encabezado. El código está debajo, cualquier ayuda se agradece enormemente.

Edit: Intentando reescribir la solicitud y cambiando la posición de la variable group_data detiene el error 401 pero no cambia los datos en el modelo.

Edit: Cambié el controlador y ahora está actualizando el campo de grupo, pero lo está sobrescribiendo completamente. Cuando intento enviar el grupo como una lista, da error esperando un entero que represente pk. Entonces mi pregunta es, ¿hay un método para parchar el modelo sin sobrescribir la información anterior?

El backend está escrito con Django y me doy cuenta de que el problema puede estar allí en lugar del front-end. También estoy publicando mi serializador y vistas en caso de que puedan ser el problema. Cualquier ayuda sería realmente apreciada.

Serializer

class UserGroupSerializer(serializers.ModelSerializer):
    groups = GroupSerializer(many=True, read_only=True,)

    class Meta:
        model = UserGroup
        fields = '__all__'

View

class UserGroupDetail(APIView):
    def patch(self, request, pk):
        usergroup = UserGroup.objects.get(pk=pk)
        serializer = UserGroupSerializer(instance=usergroup, data=request.data, partial=True)
        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)

“`

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema podría estar con la ubicación y el formato de la variable group_data en la solicitud axios. En la primera versión del código, group_data está anidada dentro del cuerpo de la solicitud, mientras que en la segunda versión se pasa como segundo argumento a axios.patch.

    Para actualizar el campo de group sin sobrescribir otros campos, puede recuperar el valor actual de group del modelo, agregar el nuevo id de grupo y luego enviar la lista actualizada dentro del objeto group_data de FormData. Parece que la segunda versión del manejador intenta hacer esto, pero la lista de group necesita ser serializada a una cadena o entero para ser aceptada por la vista de Django.

    Aquí hay algunas sugerencias de posibles cambios a probar:

    • Mueva la variable group_data fuera de la llamada a la función axios.patch y regístre sus valores para verificar que se establezcan correctamente:
      const group_data = new FormData();
      group_data.append('user', user.data.id);
      group_data.append('group', group.id);
      console.log(Array.from(group_data.entries())); // ver los pares clave-valor en la consola
      axios.patch(`http://localhost:8000/core/usergroup/${user.data.id}/`, group_data, {
          headers: {
              Authorization: `JWT ${localStorage.getItem('token')}`,
              'Content-Type': 'application/json',
          },
      }).then((res) => {
          console.log(res.data);
      }).catch((err) => {
          console.log(err);
      });
      
    • Cambie el parámetro group para que se serialice como un ID en lugar de una lista. En la segunda versión del manejador, podría hacerlo usando prev.join(',') para convertir la lista en una cadena separada por comas antes de agregarla a group_data. Luego, en el serializador, debería agregar una bandera write_only al campo groups para que solo se pueda usar para entrada, no salida:
      class UserGroupSerializer(serializers.ModelSerializer):
          groups = serializers.PrimaryKeyRelatedField(many=True, queryset=Group.objects.all(), write_only=True)
          ...
      
    • En la vista, podría modificar el método patch para manejar el campo groups por separado de los otros campos, agregando el nuevo ID de grupo a la lista existente (o creándolo si aún no existe) y luego guardando el modelo:
      class UserGroupDetail(APIView):
          def patch(self, request, pk):
              usergroup = UserGroup.objects.get(pk=pk)
              if 'group' in request.data:
                  group_id = int(request.data['group'])
                  if usergroup.group:
                      group_list = usergroup.group.split(',')
                      if not group_id in group_list:
                          group_list.append(group_id)
                      usergroup.group = ','.join(group_list)
                  else:
                      usergroup.group = str(group_id)
                  del request.data['group']
              serializer = UserGroupSerializer(instance=usergroup, data=request.data, partial=True)
              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)
      

    Estas son solo algunas ideas para explorar; puede haber otras formas de estructurar la solicitud y respuesta para lograr el resultado deseado. También puede ser útil utilizar una herramienta como Postman para probar los puntos finales de la API y ver cómo se maneja los datos en el lado del servidor.

Comments are closed.