简体   繁体   中英

Django error: 404 Page not found on get method

I am trying to get serialized data from endpoint localhost:8000/v1/test/uuid , but hitting a 404 error - what is wrong with below?

views.py

  • from uuid in response, get site object
class Test(APIView):
    def get(self, request, *args, **kwargs):
        uuid = kwargs.get('uuid')
        resp = {'site': None}
        
        site = Site.objects.get(uuid=uuid)
        resp['site'] = SiteSerializer(site).data
        return Response(resp)

urls.py

from django.conf.urls import re_path

from rest_framework.routers import DefaultRouter

from site_config import views

router = DefaultRouter()

router.register(
    r'site',
    views.SiteViewSet,
    basename='site')


urlpatterns = [
    re_path(r'^v1/', include(router.urls)),
    re_path('test/<uuid:uuid>/', views.Test.as_view(), name='test'),
]

models.py

  • site id as the pk
class Site(models.Model):
    """
    Model that represents a Site
    """
    uuid = models.UUIDField(
        default=uuid.uuid4,
        editable=False,
        unique=True)
    domain_name = models.CharField(max_length=255, unique=True)
    created = models.DateTimeField(editable=False, auto_now_add=True)
    modified = models.DateTimeField(editable=False, auto_now=True)

serializers.py

class SiteSerializer(serializers.ModelSerializer):
    class Meta:
        model = Site
        fields = [
            'uuid',
            'domain_name'
        ]

FYI - the endpoint was working when the views.py was returning all Sites, but it isn't working when I try to filter on uuid .

views.py (previously working version)

class Test(APIView):
    def get(self, request, *args, **kwargs):
        resp = {'site': None}
        site = Site.objects.all()
        resp['site'] = SiteSerializer(site, many=True).data
        return Response(resp)

Error Message on Browser:

Page not found (404)
Request Method: GET
Request URL:    http://localhost:8000/v1/test/7c018183-c952-4040-a450-e3cb58f09745/
Using the URLconf defined in site_config.urls, Django tried these URL patterns, in this order:

^v1/ ^site/$ [name='site-list']
^v1/ ^site\.(?P<format>[a-z0-9]+)/?$ [name='site-list']
^v1/ ^site/(?P<uuid>[^/.]+)/$ [name='site-detail']
^v1/ ^site/(?P<uuid>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='site-detail']
^v1/ ^$ [name='api-root']
^v1/ ^\.(?P<format>[a-z0-9]+)/?$ [name='api-root']
test/<uuid:uuid> [name='test']

urls.py

As this is a routing problem the first place to have a look should be the urls.py.

Without recreating the app it looks like there are potentially three problems there:

Analysis

1. re_path

re_path is used, a regular Django path expression is provided. The django.urls documentation has some examples that speak for themselves.

2. the path itselt

The URL path starts with v1/ while the provided configuration starts with test/ .

3. the order

As the re_path for ^v1/ matches anything beginning with v1/ the order in the pattern is important.

Anything that should available in that path must either be listed before the regex match, or be registered in the router.

Fix

urlpatterns = [
    path('v1/test/<uuid:uuid>/', views.Test.as_view(), name='test'),
    re_path(r'^v1/', include(router.urls)),
]

FYI - the endpoint was working when the views.py was returning all Sites, but it isn't working when I try to filter on uuid.

As I do not have the breakpoint analysis for your views.py code I assume that your get method inside

class Test(APIView):
    def get(self, request, *args, **kwargs):
        uuid = kwargs.get('uuid')
        resp = {'site': None}
        
        site = Site.objects.get(uuid=uuid)
        resp['site'] = SiteSerializer(site).data
        return Response(resp)

is not getting resolved by the patterns in your urls.py or the uuid is not getting through.

If the case is former here what you can do is a direct mapping of the UUID inside the get method and avoiding the kwarg.get() by doing this

class Test(APIView):
        def get(self, request, uuid, *args, **kwargs):
            uuid = uuid
            resp = {'site': None}
            
            site = Site.objects.get(uuid=uuid)
            resp['site'] = SiteSerializer(site).data
            return Response(resp)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM