DRF ModelViewSet can easily support detail views by slug via the lookup_value attribute. But what if you had compound keys (aka natural keys)? For example a url structure like
/api/computers/<organization-slug>/<computer-slug>/
A computer slug may only be unique per organization. That means different organizations may have computers with the same slug. But no computer may have the same slug in one organization. By using both slugs, we can look up a specific computer. We can use the lookup_value_regex attribute for this.
class ComputerViewSet(viewsets.ModelViewSet): queryset = Computer.objects.all() serializer_class = ComputerSerializer lookup_value_regex = r"(?P<org_slug>[^/.]+)/(?P<slug>[-\w]+)" def get_object(self): queryset = self.filter_queryset(self.get_queryset()) obj = get_object_or_404( queryset, slug=self.kwargs["slug"], organization__slug=self.kwargs["org_slug"], ) # May raise a permission denied self.check_object_permissions(self.request, obj) return obj
This works with drf-nested-routers. For example, we could add a nested /hard_drives viewset. The url values are in self.kwargs.
class HardDriveViewSet(viewsets.ModelViewSet): queryset = HardDrive.objects.all() serializer_class = HardDriveSerializer def get_queryset(self): return ( super() .get_queryset() .filter( computer__slug=self.kwargs["slug"], computer__organization__slug=self.kwargs["org_slug"], ) )