How to get specific object with router url

Viewed 41

I have a simple appointment model

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

this is the view.py where I try to get an appointment by 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)

I have tried to write the router this way, but it's not working

router = DefaultRouter(trailing_slash=False)

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

it returns me the following error message

django.core.exceptions.ImproperlyConfigured: "^my-appointments-details/(?P<pk>\d+)//(?P<pk>[^/.]+)$" is not a valid regular expression: redefinition of group name 'pk' as group 2; was group 1 at position 42
1 Answers

I got the solution. I had to refactor the view a little and views.py looks like this

class MySpecificAppointmentViewSet(ViewSet):
    permission_classes = [IsAuthenticated]

    def retrieve(self, request, pk=None):
        queryset = Appointment.objects.all()
        appointment = get_object_or_404(queryset, pk=pk)
        serializer = AppointmentDetailedSerializer(appointment)
        return Response(serializer.data)

and here is the urls.py

urlpatterns = [
path(
        "my-appointments-details/<int:pk>/",
        views.MySpecificAppointmentViewSet.as_view({'get': 'retrieve'}),
        name="my-appointment-details",
    )
]
Related