Python Django Rest Framework-无法使用“视图名称”解析超链接关系的URL;“用户详细信息”;
我正在Django Rest框架中构建一个项目,用户可以登录该项目查看他们的酒窖。 我的模型视图集工作得很好,突然出现了一个令人沮丧的错误: 无法使用视图名称“用户详细信息”解析超链接关系的URL。您可能未能将相关模型包括在API中,或者在此字段上错误配置了Python Django Rest Framework-无法使用“视图名称”解析超链接关系的URL;“用户详细信息”;,python,django,django-rest-framework,Python,Django,Django Rest Framework,我正在Django Rest框架中构建一个项目,用户可以登录该项目查看他们的酒窖。 我的模型视图集工作得很好,突然出现了一个令人沮丧的错误: 无法使用视图名称“用户详细信息”解析超链接关系的URL。您可能未能将相关模型包括在API中,或者在此字段上错误配置了lookup\u字段属性 回溯显示: [12/Dec/2013 18:35:29] "GET /bottles/ HTTP/1.1" 500 76677 Internal Server Error: /bottles/ Traceba
lookup\u字段
属性
回溯显示:
[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)),
# ...
我没有用户详细信息视图,也不知道这个问题可能来自何方。有什么想法吗
谢谢,因为它是一个
超链接模型序列化程序
您的序列化程序正在尝试解析瓶子上相关用户
的URL
由于您没有用户详细信息视图,因此无法执行此操作。因此有例外
在路由器上注册UserViewSet
难道不能解决您的问题吗
您可以在battleserializer
上定义用户字段,以显式使用UserSerializer
,而不是尝试解析URL。看李>
这段代码也应该有效
class BottleSerializer(serializers.HyperlinkedModelSerializer):
user = UserSerializer()
class Meta:
model = Bottle
fields = ('url', 'wine', 'user')
在遵循DRF快速入门指南时,我遇到了相同的错误
然后尝试浏览到/用户。我以前做过多次这样的设置,没有任何问题
我的解决方案不是在代码中,而是在替换数据库中
这次安装与以前其他安装的不同之处在于我创建本地数据库的时候
这次我跑了我的车
./manage.py migrate
./manage.py createsuperuser
跑步后立即
virtualenv venv
. venv/bin/activate
pip install django
pip install djangorestframework
而不是指南中列出的确切顺序
我怀疑数据库中没有正确创建某些内容。我不关心我的dev db,所以我删除了它,再次运行/manage.py migrate
命令,创建了一个超级用户,浏览到/users,错误就消失了
我配置DRF和db的操作顺序有问题
如果您使用的是sqlite,并且能够测试更改为新的DB,那么在剖析所有代码之前,值得一试。我也遇到了这个错误,并按如下方式解决了它:
原因是我忘了给“**-detail”(视图名称,例如:user detail)一个名称空间。因此,Django Rest框架无法找到该视图
我的项目中有一个应用程序,假设我的项目名为myproject
,应用程序名为myapp
有两个url.py文件,一个是myproject/url.py
,另一个是myapp/url.py
。我在myproject/url.py
中为应用程序提供了一个名称空间,如下所示:
url(r'', include(myapp.urls, namespace="myapp")),
我在myapp/url.py
中注册了rest框架路由器,然后得到了这个错误
我的解决方案是显式提供带有命名空间的url:
class UserSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name="myapp:user-detail")
class Meta:
model = User
fields = ('url', 'username')
它解决了我的问题。也许有人可以看看这个:
如果对超链接序列化程序使用名称空间,还需要确保序列化程序上的任何视图名称参数正确反映名称空间。例如:
urlpatterns = [
url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
url(r'^api/', include(router.urls, namespace='api')),
]
router.register(r'{pathname}', views.{ViewName}ViewSet, base_name='pathname')
对于超链接到用户详细信息视图的序列化程序字段,您需要包含一个参数,例如view\u name='api:user detail'
class UserSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name="api:user-detail")
class Meta:
model = User
fields = ('url', 'username')
导致此错误的另一个严重错误是在URL.py中不必要地定义了base_名称。例如:
urlpatterns = [
url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
url(r'^api/', include(router.urls, namespace='api')),
]
router.register(r'{pathname}', views.{ViewName}ViewSet, base_name='pathname')
这将导致上述错误。把那个基本的名字拿出来,回到一个工作的API。下面的代码将修复此错误。万岁
router.register(r'{pathname}', views.{ViewName}ViewSet)
但是,您可能不仅仅是随意添加了base_名称,您这样做可能是因为您为视图定义了自定义def get_queryset(),因此Django要求您添加base_名称。在这种情况下,您需要显式地将“url”定义为相关序列化程序的HyperlinkedEntityField。请注意,我们正在引发错误的视图的序列化程序上定义此HyperlinkedEntityField。如果我的错误是“无法使用视图名称“研究详细信息”解析超链接关系的URL”。您可能未能在API中包含相关模型,或者在此字段上错误配置了lookup\u字段
属性。我可以用以下代码修复此问题
My ModelViewSet(自定义get_queryset是我必须首先将基本名称添加到router.register()的原因):
我在URL.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')
是的。您必须在其自身上显式定义此HyperlinkedEntityField,它才能工作。您需要确保在HyperlinkedEntityField上定义的视图\u名称
与在URL.py中的基本\u名称
上定义的相同,并在其后添加“-detail”。瓶=序列化器。PrimaryKeyRelatedField(只读=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
这是我的查看功能:
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
中直接给出queryset
,因此在注册此视图集时,我必须设置base\u 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'
从myapp.views导入(UserViewSet)
从rest_framework.router导入默认路由器
路由器=默认路由器()
如果扩展GenericViewSet和ListModelMixin类,并且在列表视图中添加url字段时出现相同的错误,那是因为没有定义详细视图。请确保您正在扩展t
#models.py
class Users(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50, blank=False, null=False)
email = models.EmailField(null=False, blank=False)
class Meta:
verbose_name = "Usuario"
verbose_name_plural = "Usuarios"
def __str__(self):
return str(self.name)
#serializers.py
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Users
fields = (
'id',
'url',
'name',
'email',
'description',
'active',
'age',
'some_date',
'timestamp',
)
#views.py
class UserViewSet(viewsets.ModelViewSet):
queryset = Users.objects.all()
serializer_class = UserSerializer
#urls_api.py
router = routers.DefaultRouter()
router.register(r'users',UserViewSet, base_name='users')
urlpatterns = [
url(r'^', include(router.urls)),
]
urlpatterns = [
url(r'^admin/', admin.site.urls),
#api users
url(r'^api_users/', include('usersApi.users_urls', namespace='api')),
]
urlpatterns = [
url(r'^admin/', admin.site.urls),
#api users
url(r'^api_users/', include('usersApi.users_urls')),
]
url('api/v2/', include('api.urls', namespace='v2')),
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.NamespaceVersioning'}
class BottleSerializer(serializers.HyperlinkedModelSerializer):
class BottleSerializer(serializers.ModelSerializer):
router.register(r'messages', MessageViewSet, basename='messages')
router.register(r'messages', MessageViewSet, basename='message')
class MessageSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Message
fields = ['url', 'message', 'timestamp', 'sender', ...]
class MessageViewSet(viewsets.ModelViewSet):
serializer_class = MessageSerializer
def get_queryset(self):
return Message.objects.filter(...)