Django Rest Framework-뷰 이름 "user-detail"을 사용하여 하이퍼 링크 된 관계에 대한 URL을 확인할 수 없습니다.


108

Django Rest Framework에서 사용자가 로그인하여 와인 저장고를 볼 수있는 프로젝트를 구축하고 있습니다. 내 ModelViewSets가 제대로 작동하고 갑자기이 실망스러운 오류가 발생합니다.

보기 이름 "user-detail"을 사용하여 하이퍼 링크 된 관계에 대한 URL을 확인할 수 없습니다. 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)),
    # ...

사용자 세부 정보보기가없고이 문제의 원인이 어디인지 알 수 없습니다. 어떤 아이디어?

감사

답변:


96

그것은 왜냐하면 HyperlinkedModelSerializer당신의 시리얼 라이저는 관련에 대한 URL 해결하려고 User온을 Bottle.
사용자 세부 정보보기가 없으므로이를 수행 할 수 없습니다. 따라서 예외입니다.

  1. UserViewSet라우터에을 등록하는 것만으로 문제가 해결되지 않습니까?
  2. URL을 확인하지 않고 BottleSerializer명시 적으로 사용 하도록 사용자 필드를 정의 할 수 UserSerializer있습니다. 그에 대한 중첩 된 개체를 처리하는 데 대한 serializer 문서를 참조하십시오 .

1
감사합니다. 라우터에서 UserViewSet을 주석 처리하여 해결했습니다!
bpipat

5
그 요점은 ---- 명시 적으로 수행하십시오 --- 많은 마술은 많은 시간을 낭비하는 것입니다.
andilabs 2014-07-18

내 프로젝트 에서 무엇이 잘못 구성되었는지 지적 해 주 시겠습니까?
JJD

@ GrijeshChauhan— 감사합니다! 이제 수정되었습니다.
Carlton Gibson

작동하지 않는 이유는 django가 User 매개 변수에 대한 현재보기에서 User의 관련 데이터를 표시하기를 원했기 때문입니다. 일반적으로 사용 가능한 값 목록을 선택합니다. UserViewSet이 정의되지 않았기 때문에 웹 페이지를 렌더링하기위한 세부 정보를 가져올 수 없습니다. UserViewSet을 추가하고 기본 라우터 아래에 등록하면 모든 구성 요소를 렌더링하는 작업이 완료됩니다.
Doogle

65

이 오류도 발생하여 다음과 같이 해결했습니다.

그 이유는 "**-detail"(view_name, 예 : user-detail) 네임 스페이스를 제공하는 것을 잊었 기 때문입니다. 따라서 Django Rest Framework는 해당 뷰를 찾을 수 없습니다.

내 프로젝트에 하나의 앱이 있으며 내 프로젝트 이름이 myproject이고 앱 이름이 myapp.

두 개의 urls.py 파일 myproject/urls.pymyapp/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')

그리고 그것은 내 문제를 해결했습니다.


@boveson, 이것은 매력처럼 작동합니다! 내 편에서 몇 시간의 좌절감을 해결 해주셔서 감사합니다.
lmiguelvargasf

이것은 또한 나를 위해 일했습니다. 내 측면에서 중요한 점 중 하나는 Route에서 base_name의 정확한 철자입니다!
maggie

1
열쇠는 여기에 ..... 방지가 작동 역 네임 스페이스 접두사
boatcoder

나는 이와 같은 문제가 있었고이 답변은 3 시간의 검색 후 문제를 해결했습니다! @bovenson
Whale 52Hz

또는 drf가 권장하는대로 extra_kwargs를 사용할 수 있습니다.extra_kwargs = {'url': {'view_name': 'myapp:user-detail'}}
ChrisRob

19

어쩌면 누군가가 이것을 볼 수 있습니다 : http://www.django-rest-framework.org/api-guide/routers/

하이퍼 링크 된 serializer와 함께 네임 스페이스를 사용하는 경우 serializer의 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')

1
요약하면, api에 네임 스페이스를 제공하면 제목에 오류가 발생합니다. 여러 곳에서 변경하지 않는 한 그렇게하고 싶지 않을 것입니다.
Mark

나를 위해 일했습니다! 내 프로젝트 urls.py에서 내 두 번 중첩되었습니다 newsite: (1) newsite/urls.py(장고에 의해 생성됨) (2) polls/urls.py(3) polls/api/v1/urls.py ............ 저는 중첩 된 이름을 언급해야합니다.url = serializers.HyperlinkedIdentityField(view_name="polls:polls_api:user-detail")
Grijesh Chauhan

12

이 오류를 일으키는 또 다른 불쾌한 실수는 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'을 해당 serializer에 대한 HyperlinkedIdentityField로 명시 적으로 정의해야합니다. 오류를 발생시키는 뷰의 SERIALIZER에서이 HyperlinkedIdentityField를 정의하고 있습니다. 내 오류가 "뷰 이름"study-detail "을 사용하여 하이퍼 링크 된 관계에 대한 URL을 확인할 수 없습니다. API에 관련 모델을 포함하지 못했거나이 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 자체를 명시 적으로 정의해야합니다. 그리고 view_nameHyperlinkedIdentityField에 정의 된 내용이 base_name뒤에 '-detail'이 추가 된 urls.py에서 정의한 것과 동일한 지 확인해야합니다.


2
이것은 나를 위해 일했지만 전체 경로를 넣어야했습니다 <app_name>:studies-detail. 예를 들어 내 앱이 호출 tanks되면 전체 경로는 HyperlinkedIdentityField(view_name="tanks:studies-detail"). 이를 알아 내기 위해 django-exensions show_urls 명령을 사용하여 라우터가 자동으로 만드는 전체 경로와 레이블을 확인했습니다.
dtasev

10

이 코드도 작동합니다.

class BottleSerializer(serializers.HyperlinkedModelSerializer):

  user = UserSerializer()

  class Meta:
    model = Bottle
    fields = ('url', 'wine', 'user')

3
가치는 그 지적 UserSerializer과 같이, (그것이 가져올 준비가되지 않은) 구현해야합니다 django-rest-framework.org/api-guide/serializers
Caumons

이것은 나를 위해 일했지만 작동하려면 router.register (r'bottles ', views.BottleViewSet, base_name ='bottles ')를 router.register (r'bottles', views.BottleViewSet)로 변경해야했습니다. 이 변경이 필요한 이유를 모르겠습니다.
manpikin

4

내 URL에 네임 스페이스를 추가 한 후이 오류가 발생했습니다.

 url('api/v2/', include('api.urls', namespace='v2')),

내 urls.py에 app_name 추가

내 프로젝트의 settings.py에서 나머지 프레임 워크 API에 대해 NamespaceVersioning을 지정하여이 문제를 해결했습니다.

REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.NamespaceVersioning'}

3

오늘 나는 같은 오류가 발생했으며 아래 변경 사항이 나를 구해줍니다.

변화

class BottleSerializer(serializers.HyperlinkedModelSerializer):

에:

 class BottleSerializer(serializers.ModelSerializer):

2

동일한 오류이지만 다른 이유 :

사용자 지정 사용자 모델을 정의하고 새 필드는 없습니다.

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파일로 인한 오류 메시지입니다 .

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.


이전 게시물이지만 "# <-base_name은 'user'대신 'customuser'여야합니다."라는 의견이 제 하루를 절약했습니다. 감사!
Hannon César

1

GenericViewSetListModelMixin 클래스를 확장하고 목록보기에 url 필드를 추가 할 때 동일한 오류가 발생 하는 경우 세부보기를 정의하지 않았기 때문입니다. RetrieveModelMixin 믹스 인을 확장하고 있는지 확인하십시오 .

class UserViewSet (mixins.ListModelMixin,
                   mixins.RetrieveModelMixin,
                   viewsets.GenericViewSet):

1

HyperlinkedModelSerializer길을 갖는 것에 동의하지 않는 것 같습니다 namespace. 내 지원서에서 두 가지를 변경했습니다.

# rootapp/urls.py
urlpatterns = [
    # path('api/', include('izzi.api.urls', namespace='api'))
    path('api/', include('izzi.api.urls')) # removed namespace
]

가져온 URL 파일에서

# app/urls.py
app_name = 'api' // removed the app_name

도움이 되었기를 바랍니다.


0

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

가이드에 나열된 정확한 순서 대신.

DB에 뭔가 제대로 생성되지 않은 것 같습니다. 내 dev db에 신경 쓰지 않았으므로 삭제하고 실행했습니다../manage.py migrate 명령을 다시 슈퍼 사용자를 만들고 / users를 찾아보고 오류가 사라졌습니다.

DRF와 db를 구성한 작업 순서에 문제가있었습니다.

sqlite를 사용하고 있고 새로운 DB 로의 변경을 테스트 할 수 있다면 모든 코드를 분석하기 전에 시도해 볼 가치가 있습니다.


0

병 = serializers.PrimaryKeyRelatedField (read_only = True)

read_only를 사용하면 모델의 다른보기에 링크하지 않고도 필드를 나타낼 수 있습니다.


0

데이터베이스에서 슬러그 값이 비어있을 때 DRF 3.7.7에서 오류가 발생했습니다 ( ''와 같음).


0

이 문제가 발생하여 generics.RetrieveAPIView뷰셋에 기본 클래스로 추가하여 해결했습니다 .


0

거의 2 시간 동안이 오류가 발생했습니다.

/ api_users / users / 1 /에서 부적절하게 구성됨보기 이름 "users-detail"을 사용하여 하이퍼 링크 된 관계에 대한 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')),

]

그리고 나는 마침내 내 문제를 해결하므로 누구든지 그 이유를 알 수 있습니다.


0

serializer에서 'id'및 'url'필드를 생략하면 문제가 발생하지 않습니다. 어쨌든 json 객체에서 반환되는 ID를 사용하여 게시물에 액세스 할 수 있으므로 프런트 엔드를 구현하기가 훨씬 더 쉽습니다.


0

나는 같은 문제가 있었다, 나는 당신이 당신의

get_absolute_url

객체 모델의 메소드 입력 값 (** kwargs) 제목. lookup_field에서 정확한 필드 이름을 사용하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.