Django Rest Framework – 无法使用视图名称“user-detail”parsing超链接关系的URL
我正在Django Rest框架中build立一个项目,用户可以login查看他们的酒窖。 我的ModelViewSets工作得很好,突然之间,我得到了这个令人沮丧的错误:
无法使用视图名称“user-detail”parsing超链接关系的URL。 您可能未能在您的API中包含相关模型,或在此字段上错误地configuration了
lookup_field
属性。
追溯显示:
[12/Dec/2013 18:35:29] "GET /bottles/ HTTP/1.1" 500 76677 Internal Server Error: /bottles/ Traceback (most recent call last): File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/django/core/handlers/base.py", line 114, in get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/viewsets.py", line 78, in view return self.dispatch(request, *args, **kwargs) File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 57, in wrapped_view return view_func(*args, **kwargs) File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/views.py", line 399, in dispatch response = self.handle_exception(exc) File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/views.py", line 396, in dispatch response = handler(request, *args, **kwargs) File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/mixins.py", line 96, in list return Response(serializer.data) File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/serializers.py", line 535, in data self._data = [self.to_native(item) for item in obj] File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/serializers.py", line 325, in to_native value = field.field_to_native(obj, field_name) File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/relations.py", line 153, in field_to_native return self.to_native(value) File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/relations.py", line 452, in to_native raise Exception(msg % view_name) Exception: 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.
我有一个自定义的电子邮件用户模型,在models.py中的瓶子模型是:
class Bottle(models.Model): wine = models.ForeignKey(Wine, null=False) user = models.ForeignKey(User, null=False, related_name='bottles')
我的序列号:
class BottleSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Bottle fields = ('url', 'wine', 'user') class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('email', 'first_name', 'last_name', 'password', 'is_superuser')
我的看法:
class BottleViewSet(viewsets.ModelViewSet): """ API endpoint that allows bottles to be viewed or edited. """ queryset = Bottle.objects.all() serializer_class = BottleSerializer class UserViewSet(ListCreateAPIView): """ API endpoint that allows users to be viewed or edited. """ queryset = User.objects.all() serializer_class = UserSerializer
最后是url:
router = routers.DefaultRouter() router.register(r'bottles', views.BottleViewSet, base_name='bottles') urlpatterns = patterns('', url(r'^', include(router.urls)), # ...
我没有用户的详细信息视图,我不知道这个问题可能来自哪里。 有任何想法吗?
谢谢
因为它是一个HyperlinkedModelSerializer
你的序列化程序正在试图parsingBottle
上相关User
的URL。
由于您没有用户详细信息视图,因此无法执行此操作。 因此例外。
- 不会只注册
UserViewSet
与路由器解决您的问题? - 您可以在
BottleSerializer
上定义用户字段,以显式使用UserSerializer
而不是尝试parsingURL。 查看关于处理嵌套对象的序列化程序文档 。
我也遇到了这个错误,并解决它,如下所示:
原因是我忘了给“** – 细节”(view_name,例如:user-detail)一个命名空间。 所以,Django Rest Framework找不到这个视图。
我的项目中有一个应用程序,假设我的项目名称是myproject
,应用程序名称是myapp
。
有两个urls.py文件,一个是myproject/urls.py
,另一个是myapp/urls.py
我在myproject/urls.py
给应用程序一个命名空间,就像:
url(r'', include(myapp.urls, namespace="myapp")),
我在myapp/urls.py
注册了其余的框架路由器,然后得到这个错误。
我的解决scheme是明确地提供带有名称空间的URL:
class UserSerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="myapp:user-detail") class Meta: model = User fields = ('url', 'username')
它解决了我的问题。
这个代码也应该可以工作。
class BottleSerializer(serializers.HyperlinkedModelSerializer): user = UserSerializer() class Meta: model = Bottle fields = ('url', 'wine', 'user')
也许有人可以看看这个: http : //www.django-rest-framework.org/api-guide/routers/
如果对超链接序列化器使用命名空间,则还需要确保序列化器上的任何view_name参数都能正确反映命名空间。 例如:
urlpatterns = [ url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), url(r'^api/', include(router.urls, namespace='api')), ]
您需要为超链接到用户详细信息视图的序列化程序字段包含一个参数,例如view_name='api:user-detail'
。
class UserSerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="api:user-detail") class Meta: model = User fields = ('url', 'username')
导致此错误的另一个令人讨厌的错误是在您的urls.py中不必要地定义了base_name。 例如:
router.register(r'{pathname}, views.{ViewName}ViewSet, base_name='pathname')
这将导致上述错误。 从那里获得base_name,并返回到一个工作的API。 下面的代码将修复错误。 万岁!
router.register(r'{pathname}, views.{ViewName}ViewSet)
然而,你可能不是随意添加base_name,你可能已经这样做了,因为你为View定义了一个自定义的def get_queryset(),所以Django强制你添加base_name。 在这种情况下,您需要显式地将“url”定义为相关序列化程序的HyperlinkedIdentityField。 请注意,我们正在定义这个超链接的authentication字段的视图抛出错误的序列化。 如果我的错误是“无法为使用视图名称的超链接关系parsingURL”study-detail“。您可能未能在您的API中包含相关模型,或者在此字段上错误地configuration了lookup_field
属性。 我可以用下面的代码解决这个问题。
我的ModelViewSet(自定义get_queryset是为什么我必须添加base_name到router.register()在第一位):
class StudyViewSet(viewsets.ModelViewSet): serializer_class = StudySerializer '''custom get_queryset''' def get_queryset(self): queryset = Study.objects.all() return queryset
我在urls.py中注册了这个ModelViewSet:
router.register(r'studies', views.StudyViewSet, base_name='studies')
这里是钱! 那么我可以这样解决:
class StudySerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="studies-detail") class Meta: model = Study fields = ('url', 'name', 'active', 'created', 'time_zone', 'user', 'surveys')
是的。 你必须明确地定义这个HyperlinkedIdentityField本身才能工作。 而且你需要确保在HyperlinkedIdentityField上定义的view_name
与在urls.py中的base_name
上定义的相同,后面添加了“-detail”。
当我按照DRF快速入门指南http://www.django-rest-framework.org/tutorial/quickstart/ ,然后尝试浏览到/用户时,遇到了同样的错误。 我已经做了这个设置多次,没有问题。
我的解决scheme不是在代码中,而是在replace数据库。
这个安装和其他之间的区别是当我创build本地数据库。
这次我跑了我的
./manage.py migrate ./manage.py createsuperuser
跑完之后立即
virtualenv venv . venv/bin/activate pip install django pip install djangorestframework
而不是指南中列出的确切顺序。
我怀疑在DB中没有正确创build。 我不关心我的开发数据库,所以我删除它,再次运行./manage.py migrate
命令,创build一个超级用户,浏览到/用户和错误消失了。
有些问题与我configurationDRF和数据库的操作顺序有关。
如果您正在使用sqlite并且能够testing更改为新的数据库,那么在您parsing所有代码之前,这是值得尝试的。
Bottle = serializers.PrimaryKeyRelatedField(read_only = True)
read_only允许您表示该字段,而不必将其链接到模型的另一个视图。
同样的错误,但不同的原因:
我定义了一个自定义用户模型,没有新的字段:
from django.contrib.auth.models import (AbstractUser) class CustomUser(AbstractUser): """ custom user, reference below example https://github.com/jonathanchu/django-custom-user-example/blob/master/customuser/accounts/models.py # original User class has all I need # Just add __str__, not rewrite other field - id - username - password - email - is_active - date_joined - method, email_user """ def __str__(self): return self.username
这是我的观点function:
from rest_framework import permissions from rest_framework import viewsets from .models import (CustomUser) class UserViewSet(viewsets.ModelViewSet): permission_classes = (permissions.AllowAny,) serializer_class = UserSerializer def get_queryset(self): queryset = CustomUser.objects.filter(id=self.request.user.id) if self.request.user.is_superuser: queryset = CustomUser.objects.all() return queryset
由于我没有直接在UserViewSet
提供查询集, base_name
当我注册这个视图集时,我必须设置base_name。 这是我urls.py
文件导致的错误信息:
from myapp.views import (UserViewSet) from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(r'users', UserViewSet, base_name='customuser') # <--base_name needs to be 'customuser' instead of 'user'
您需要一个与您的模型名称相同的base_name
– customuser
。