Reputation: 1771
I have an api list of posts with Django Rest Framework. Knowing that I slugify my post title, whenever the user provides a title to her post, I want to capture the post api detail with the pk (the default lookup field in DRF) when the slug object is not provided, or using the slug field if the post has a title.
In my api folder of the post application, I wrote the following views.py:
class PostDetailAPIView(generics.RetrieveAPIView):
queryset = Post.objects.all()
serializer_class = serializers.PostDetailSerializer
try:
lookup_field = 'slug'
except:
lookup_field = 'pk'
And provided the corresponding urls.py:
urlpatterns = [
url(r'^$', PostListAPIView.as_view(), name='list-api'),
url(r'^(?P<slug>[\w-]+)/$', PostDetailAPIView.as_view(),
name='detail-api'),
url(r'^(?P<pk>\d+)/$', PostDetailAPIView.as_view(), name='detail-
api'),
]
This approach works perfectly when a post has a slugified (title) lookup. But the post detail view for a post with no slug shows the following:
HTTP 404 Not Found
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"detail": "Not found."
}
Any suggestions on how to show the post api detail for either a pk or a slug fields lookup? Preferably with no code repitition in the urls.py.
Upvotes: 0
Views: 3102
Reputation: 882
First: Your urls.py works with the first matched url. So it can not find your second url.
Second: In my opinion you should either stick to the "pk" Version (which is what REST states) or the slug version for the lookup. So in general i would anticipate the process of either looking for a pk or a slug.
I know this does not yet solve your answer to 100% but it should provide you a overlook on what's going on and what a REST Endpoint might look like.
Upvotes: 1
Reputation: 36
Using two different parameter for a single view seems to be like a bad practice to me, i will suggest you use one of them and in your view, you do a try/catch since pk will be of integer type and title will be of string type, you can check the type of the url parameter then do your logic
Upvotes: 0