2

I use Django 1.11 + Django REST Framework. I'm trying to get detailed data about distinct record using generic RetrieveAPIView from Django REST Framework and server returns "HTTP 404 Not Found" result, i.e. no data.

models.py file:

class TestPage( models.Model):
    title = models.CharField(  size = 120)
    counter = models.IntegerField( default = 0)
    def __unicode__(self):
        return u'' + self.title

serializers.py file:

class TestPageSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('id', 'title', 'counter',)
        model = models.TestPage

urls.py file:

urlpatterns = [
    url( r'^admin/', admin.site.urls),
    url( r'^api/', include( 'rest_framework.urls')), 
    url( r'^api/', include( 'testpages.urls')),  
    ]

testpages/urls.py file:

urlpatterns = [
    url( r'^$', views.TestPageList.as_view()),
    url( r'^(?P<id>)\d+/$', views.TestPageDetail.as_view()),  
    ]

and at last views.py file:

class TestPageList(generics.ListAPIView):
    lookup_field = 'id'
    queryset = TestPage.objects.all()
    serializer_class = TestPageSerializer

class TestPageDetail(generics.RetrieveAPIView):
    lookup_field = 'id'
    queryset = TestPage.objects.all()
    serializer_class = TestPageSerializer
    # def get_object( self):
    #    print self.kwargs

If I request "http://127.0.0.1:8000/api/" for all records in the list, server returns all records. But if I want to get record by id using "http://127.0.0.1:8000/api/1/" for example, I get the empty result like in the photo below.

[![enter image description here][1]][1]

If I uncomment get_object()-function in last 2 lines, I can see {'id': u''} in terminal i.e. server gets empty parameter 'id'.

What wrong with this code?

1
  • You can combine both of them into a single ViewSet Commented Aug 29, 2018 at 12:36

2 Answers 2

3

The issue is your regular expression matching for id, you're putting \d+ outside of the matching group when it's actually what you want to match:

url(r'^(?P<id>\d+)/$', views.TestPageDetail.as_view())

By the way, to be good REST citizen, you shouldn't add the / at the end of a URL for a specific object.

Note: As mentioned by JPG, adding a name for the resource you're fetching (plural) would be proper RESTful:

url(r'^pages/(?P<id>\d+)$', views.TestPageDetail.as_view())

This way, you fetch page nr. 1 at /api/pages/1

Sign up to request clarification or add additional context in comments.

2 Comments

I missed that regex part. +1 for that :)
Thank you very much, dirkgroten! ِActually I misplaced ')'.
1

The original problem was the closing parathesis (the regex expression), you were misplaced that.

urlpatterns = [
    url(r'^$', views.TestPageList.as_view()),
    url(r'^(?P<id>\d+)/$', views.TestPageDetail.as_view()),
                    ^^^ here
]

Apart from that, You should change the urls patterns to a sensible form, as

#testpages/urls.py
urlpatterns = [
    url(r'^test/$', views.TestPageList.as_view()),
    url(r'^test/(?P<id>\d+)/$', views.TestPageDetail.as_view()),
]

then the list-api will be available on /api/test/ endpoint
and the detail-api will be available on /api/test/{id}/

1 Comment

Thank you for the quick answer. I don't think the problem is in this urls-file. The thing is the first line in urls.py (for TestPageList.as_view()) works nice and returns list of records. The problem only with the second one. 'id' == '' in result. Can be problem in Django version (I use 1.11, not 2.x)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.