Django Rest Framework - не удалось разрешить URL для гиперссылочных отношений с использованием имени представления " user-detail"
Я строю проект в Django Rest Framework, где пользователи могут войти в систему, чтобы просмотреть свой винный погреб. Мои ModelViewSets работали просто отлично, и вдруг я получаю эту неприятную ошибку:
не удалось разрешить URL-адрес для гиперссылочной связи с использованием имени представления "user-detail". Возможно, вы не включили соответствующую модель в свой API или неправильно настроили
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)),
# ...
у меня нет подробного представления пользователя, и я не вижу, откуда эта проблема может возникнуть. Есть идеи?
спасибо
12 ответов:
потому что это
HyperlinkedModelSerializer
ваш сериализатор пытается разрешить URL для связанногоUser
наBottle
.
Поскольку у вас нет подробного представления пользователя, он не может этого сделать. Отсюда и исключение.
- не будет просто регистрация
UserViewSet
с маршрутизатором решить вашу проблему?- вы можете определить поле пользователя на вашем
BottleSerializer
чтобы явно использоватьUserSerializer
вместо того чтобы пытаться разрешить URL-адрес. Смотрите сериализатор документов по работе с вложенные объекты для этого.
я тоже наткнулся на эту ошибку и решил ее следующим образом:
причина в том, что я забыл дать "**-detail" (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
, а затем получил эту ошибку.мое решение состояло в том, чтобы предоставить url-адрес с пространством имен явно:
class UserSerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="myapp:user-detail") class Meta: model = User fields = ('url', 'username')
и это решило мою проблему.
может быть, кто-то может взглянуть на это : 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')
этот код тоже должен работать.
class BottleSerializer(serializers.HyperlinkedModelSerializer): user = UserSerializer() class Meta: model = Bottle fields = ('url', 'wine', 'user')
еще одна неприятная ошибка, которая вызывает эту ошибку, заключается в том, что имя base_name излишне определено в вашем urls.py например:
router.register(r'{pathname}, views.{ViewName}ViewSet, base_name='pathname')
это приведет к ошибке, упомянутых выше. Получите это имя базы оттуда и вернитесь к рабочему API. Приведенный ниже код исправит ошибку. Ура!
router.register(r'{pathname}, views.{ViewName}ViewSet)
однако вы, вероятно, не просто произвольно добавили base_name, вы могли бы сделать это, потому что вы определили пользовательский def get_queryset() для представления и поэтому Django мандаты, которые вы добавляете base_name. В этом случае вам нужно будет явно определить " url " как HyperlinkedIdentityField для рассматриваемого сериализатора. Обратите внимание, что мы определяем это HyperlinkedIdentityField в СЕРИАЛИЗАТОРЕ представления, которое выдает ошибку. Если моя ошибка была "не удалось разрешить URL для гиперссылочных отношений с использованием имени представления "исследование-деталь". Возможно, вы не включили соответствующую модель в свой API или неправильно настроили
lookup_field
атрибут в этом поле." Я мог бы исправить это с помощью следующего кода.мой ModelViewSet (пользовательский get_queryset-это то, почему я должен был добавить base_name к маршрутизатору.регистрация() в первую очередь):
class StudyViewSet(viewsets.ModelViewSet): serializer_class = StudySerializer '''custom get_queryset''' def get_queryset(self): queryset = Study.objects.all() return queryset
моя регистрация маршрутизатора для этого ModelViewSet в urls.py:
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 на себе, чтобы он работал. И вам нужно сделать конечно, что
view_name
определяется на поле HyperlinkedIdentityField так же, как вы определили наbase_name
in urls.py с добавлением "- детали " после него.
та же ошибка, но другая причина:
Я определяю пользовательскую модель пользователя, ничего нового поля:
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
так как я не дал
queryset
непосредственно вUserViewSet
, Я должен установитьbase_name
когда я регистрирую этот набор представлений. Вот где мое сообщение об ошибке, вызванноеurls.py
file: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
.
Если вы расширяете границы GenericViewSet и ListModelMixin классы, и имеют ту же ошибку при добавлении url поле в виде списка, это потому, что вы не определяете детальный вид. Убедитесь, что вы расширяете RetrieveModelMixin mixin:
class UserViewSet (mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
я столкнулся с той же ошибкой, когда я следовал руководству быстрого запуска DRF http://www.django-rest-framework.org/tutorial/quickstart/ и затем пытается перейти к /users. Я делал эту настройку много раз раньше без проблем.
мое решение было не в коде, а в замене базы данных.
разница между этой установкой и другими ранее была, когда я создал локальную базу данных.
на этот раз я побежал мой
./manage.py migrate ./manage.py createsuperuser
сразу после
virtualenv venv . venv/bin/activate pip install django pip install djangorestframework
вместо точного порядка, указанного в руководстве.
Я подозревал, что что-то не правильно создал в БД. Я не заботился о моей dev db, поэтому я удалил его и запустил
./manage.py migrate
команда еще раз, создал суперпользователя, просматривал /пользователей и ошибка исчезла.что-то было проблематично с порядком операций, в котором я настроил DRF и db.
Если вы используете sqlite и могут протестировать изменение на новую БД, тогда стоит попробовать, прежде чем вы перейдете к разбору всего вашего кода.
бутылка = сериализатор.PrimaryKeyRelatedField (read_only=True)
read_only позволяет представлять поле без необходимости связывать его с другим представлением модели.
я столкнулся с этой же проблемой и решил ее, добавив
generics.RetrieveAPIView
в качестве базового класса для Мой viewset.
Я застрял в этой ошибке почти на 2 часа:
неправильно сконфигурирован в /api_users / users/1/ Не удалось разрешить URL-адрес для гиперссылочной связи с использованием имени представления "пользователи-сведения". Возможно, вы не включили соответствующую модель в свой API или неправильно настроили
lookup_field
атрибут в этом поле.когда я наконец получаю решение, но я не понимаю, почему, поэтому мой код:
#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)), ]
но в моих основных url, это было:
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')), ]
и я, наконец, решить мою проблему, так что любой может дать мне знать, почему, bests.