如何使用`path`函数代替`url`函数

时间:2018-08-17 02:39:28

标签: python django django-rest-framework

我正在学习如何使用django-rest-framework建立我的前端分离项目。我遵循django官方文档,使用path函数而不是url函数进行开发。但是,当我添加django-rest-framework时,我发现django-rest-framework仍在使用url函数。为了保持代码的一致性,我编写了以下代码:

在“ quickstart / urls.py”中(“ quickstart”是我的应用名称)

from django.urls import path, include
from rest_framework import routers

from quickstart import views

router = routers.DefaultRouter()
router.register('users', views.UserViewSet)
router.register('groups', views.GroupViewSet)

app_name = 'quickstart'
urlpatterns = [
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls')),
]

在“ tutorial / urls.py”中(“ tutorial”是项目名称)

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('quickstart/', include('quickstart.urls')),
]

但是,程序出现问题。当我访问127.0.0.1/quickstart/users时,出现以下错误:

Internal Server Error: /quickstart/users/
Traceback (most recent call last):
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\relations.py", line 376, in to_representation
    url = self.get_url(value, self.view_name, request, format)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\relations.py", line 314, in get_url
    return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\reverse.py", line 50, in reverse
    url = _reverse(viewname, args, kwargs, request, format, **extra)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\reverse.py", line 63, in _reverse
    url = django_reverse(viewname, args=args, kwargs=kwargs, **extra)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\django\urls\base.py", line 90, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\django\urls\resolvers.py", line 622, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'user-detail' not found. 'user-detail' is not a valid view function or pattern name.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\django\core\handlers\base.py", line 124, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\viewsets.py", line 103, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\views.py", line 483, in dispatch
    response = self.handle_exception(exc)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\views.py", line 443, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\views.py", line 480, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\mixins.py", line 48, in list
    return Response(serializer.data)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\serializers.py", line 765, in data
    ret = super(ListSerializer, self).data
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\serializers.py", line 262, in data
    self._data = self.to_representation(self.instance)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\serializers.py", line 683, in to_representation
    self.child.to_representation(item) for item in iterable
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\serializers.py", line 683, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\serializers.py", line 527, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "C:\dev\tomorrow-headline\venv\lib\site-packages\rest_framework\relations.py", line 391, in to_representation
    raise ImproperlyConfigured(msg % self.view_name)
django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "user-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
[17/Aug/2018 10:33:18] "GET /quickstart/users/ HTTP/1.1" 500 151754

此代码完全在官方的django-rest-framework教程中编写,只是对“ urls”文件的简单修改。所以我的问题是:如何用url函数替换path函数?我是否需要修改其他部分的代码?

编辑===================

我更改了tutorial / urls.py中的代码:

path('quickstart/', include('quickstart.urls')),

from quickstart import urls 
...
path('quickstart/', include(urls.urlpatterns)),

此代码可以正常工作,但是为什么呢?

======================

非常感谢。

2 个答案:

答案 0 :(得分:0)

我当前正在使用Django==2.0.5djangorestframework==3.8.2

使用url时,我没有遇到任何问题。我的代码绝对是一种魅力。我建议您不要将 url 更改为 path 。 以下是我的代码库中的示例

urls.py

urlpatterns = [
    url(r'^abc/', include('abc.urls', namespace="abc")),
    url(r'^xyz/', include('xyz.urls', namespace="xyz")),
]

abc / urls.py

from django.conf.urls import url

from .views import *

app_name = 'abc'
urlpatterns = [
    url(r'^update_xyz', update_xyz, ),
]

答案 1 :(得分:0)

经过一段时间的学习,我对Djangodjango-rest-framework的理解逐渐加深。我发现问题不在url()函数和path()函数中,但是视图有问题。

在我的代码中,我使用ModelViewSet来组织视图。编写lookup_field时没有添加UserViewSet属性。这将导致路由器处理请求,而无需知道哪个url参数调用UserViewSet的详细信息部分。

在我的代码中,我添加了lookup_field属性来修复此错误。代码显示如下(views.py):

from rest_framework import viewsets

from articles.models import Article
from articles.serializers import ArticleSerializer


class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

    lookup_field = 'slug'

我对先前的代码做了一些重构工作,因此当前代码可能看起来与先前的代码不同。但这不是大问题。