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.

Cómo obtener un objeto específico utilizando la URL del enrutador.

Tengo un modelo de cita simple

class Appointment(models.Model):
    title = models.CharField(max_length=50)
    start_date_time = models.DateTimeField()
    end_date_time = models.DateTimeField()
    description = models.TextField()
    user = models.ForeignKey(
        User, on_delete=models.CASCADE, null=True, related_name="user"
    )
    advanced_user = models.ForeignKey(
        AdvancedUser, on_delete=models.CASCADE, null=True, related_name="advanced_user"
    )

    appointment_type = models.CharField(
        blank=True, choices=APPOINTMENT_TYPE_CHOICES, max_length=10
    )

    objects = AppointmentManager()

Este es el archivo view.py donde intento obtener una cita por pk

class MySpecificAppointmentViewSet(ModelViewSet):
    permission_classes = [IsAuthenticated]
    serializer_class = AppointmentDetailedSerializer
    pagination_class = None

    def get_queryset(self, pk=None):
        if getattr(self, "swagger_fake_view", False):
            return Appointment.objects.none()
        return Appointment.objects.get(pk=pk)

He intentado escribir el enrutador de esta manera, pero no funciona

router = DefaultRouter(trailing_slash=False)

router.register(
    prefix=r'my-appointments-details/(?P<pk>\d+)/',
    viewset=views.MySpecificAppointmentViewSet,
    basename="my-appointment-details"
)

Me devuelve el siguiente mensaje de error

django.core.exceptions.ImproperlyConfigured: "^my-appointments-details/(?P<pk>\d+)//(?P<pk>[^/.]+)$" no es una expresión regular válida: redefinición del nombre del grupo 'pk' como grupo 2; era el grupo 1 en la posición 42
Tags:  ,

Answer

  1. Avatar for davy.ai

    El mensaje de error indica que hay un problema con la expresión regular utilizada en el enrutador. Parece que la expresión regular está definiendo dos grupos con el mismo nombre ‘pk’, lo cual no está permitido.

    Para solucionar este problema, puedes modificar la expresión regular en el enrutador para utilizar un nombre diferente para el segundo grupo, por ejemplo:

    router.register(
        prefix=r'my-appointments-details/(?P<pk>\d+)/',
        viewset=views.MySpecificAppointmentViewSet,
        basename="my-appointment-details"
    )
    

    En este caso, el primer grupo se llama ‘pk’, como antes, pero el segundo grupo se llama de manera diferente para evitar el conflicto.

    Además, es posible que también debas modificar el método get_queryset en la vista para recuperar realmente la cita usando el pk proporcionado. Aquí tienes una posible implementación:

    class MySpecificAppointmentViewSet(ModelViewSet):
        permission_classes = [IsAuthenticated]
        serializer_class = AppointmentDetailedSerializer
        pagination_class = None
    
        def get_queryset(self):
            if getattr(self, "swagger_fake_view", False):
                return Appointment.objects.none()
            pk = self.kwargs.get('pk')
            return Appointment.objects.filter(pk=pk)
    

    Ten en cuenta que el parámetro pk debe obtenerse del atributo kwargs, que contiene los valores capturados por la expresión regular en el enrutador. El queryset también debe utilizar el método filter en lugar de get, ya que get solo es adecuado para recuperar una única instancia por su clave primaria.

Comments are closed.