Django Rest Framework - 보기 이름 "user-detail"을 사용하여 하이퍼링크된 관계의 URL을 확인할 수 없습니다.
저는 장고레스트 프레임워크에서 사용자가 로그인하여 와인 저장실을 볼 수 있는 프로젝트를 구축하고 있습니다.내 모델 보기세트가 제대로 작동했는데 갑자기 다음과 같은 답답한 오류가 발생했습니다.
보기 이름 "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)),
# ...
사용자 세부 정보 보기가 없고 이 문제의 원인을 알 수 없습니다.아이디어 있어요?
감사해요.
왜냐하면 그것은.HyperlinkedModelSerializer
.User
의 신의에Bottle
.
사용자 세부 정보 보기가 없으므로 이 작업을 수행할 수 없습니다.따라서 예외입니다.
- 등록만 하지는 않을 것입니다.
UserViewSet
라우터로 당신의 문제를 해결합니까? - 는 에서사정있수다에서 할 수 .
BottleSerializer
명적으사위해기용하로를 명시적으로UserSerializer
URL을 해결하려고 하는 것보다.이에 대한 자세한 내용은 중첩된 개체 처리에 대한 직렬화 도구 설명서를 참조하십시오.
저도 이 오류를 발견하고 다음과 같이 해결했습니다.
그 이유는 "**-detail"(view_name, 예: user-detail)에 네임스페이스를 지정하는 것을 잊었기 때문입니다.그래서 장고 레스트 프레임워크는 그 뷰를 찾을 수 없었습니다.
내 프로젝트에 앱이 하나 있는데, 내 프로젝트 이름이myproject
앱 은 고앱이름은그리은이▁name입니다.myapp
.
개의.py 파일이 , 는 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'
사용자 세부 정보 보기에 하이퍼링크된 serializer 필드입니다.
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에 대한 사용자 정의 defet_queryset()을 정의했기 때문에 그렇게 했을 수 있습니다. 따라서 Django는 base_name을 추가해야 합니다.이 경우 'url'을 해당 직렬화 프로그램의 하이퍼링크된 ID 필드로 명시적으로 정의해야 합니다.오류를 발생시키는 뷰의 직렬화 프로그램에서 이 하이퍼링크된 ID 필드를 정의하고 있습니다. 제 가 "name "study-detail"을 할 수 ."였다면 API를 했을 수 .lookup_field
이▁i성."속이▁"의▁code▁following▁.' 다음 코드로 수 .저는 다음 코드로 이것을 고칠 수 있습니다.
My 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
이 모델 뷰에 대한 라우터 등록URL로 설정합니다.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')
이를 그 합니다. 이 하 링 ID 정 퍼 야 작 해 니 합그리고 당신은 확실히 해야 합니다.view_name
은 HyperlinkedIdentityField에 된 내용과 .base_name
뒤에 '-'자가 추가된 urls.py .
이 코드도 작동해야 합니다.
class BottleSerializer(serializers.HyperlinkedModelSerializer):
user = UserSerializer()
class Meta:
model = Bottle
fields = ('url', 'wine', 'user')
오늘도 같은 오류가 발생했고 아래의 변경 사항이 나를 구해줍니다.
바꾸다
class BottleSerializer(serializers.HyperlinkedModelSerializer):
대상:
class BottleSerializer(serializers.ModelSerializer):
URL에 네임스페이스를 추가한 후 이 오류가 발생했습니다.
url('api/v2/', include('api.urls', namespace='v2')),
그리고 내 urls.py 에 app_name을 추가합니다.
프로젝트의 settings.py 에서 나머지 프레임워크 API에 대해 네임스페이스 버전을 지정하여 이 문제를 해결했습니다.
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.NamespaceVersioning'}
TL;DR: 라우터 기본 이름에서 후행 's'를 제거하는 것만큼 간단할 수 있습니다.직렬화기에서 URL 필드를 정의할 필요가 없습니다.
원본 포스터의 경우 상단 답변에 제시된 대로 UserViewSet 등록만으로 문제가 해결되었습니다.
그러나 ViewSet을 모두 등록했는데도 다른 사용자가 이 문제를 겪고 있다면 무엇이 잘못되고 있는지 파악한 것 같습니다. 그리고 여기 있는 다른 사용자보다 더 깨끗한 솔루션을 찾았습니다.
제 경우 사용자 지정 get_queryset() 함수를 사용하여 ViewSet을 생성하려고 시도한 후 이 문제가 발생했습니다.ViewSet의 queryset 필드를 사용자 지정 get_queryset() 함수로 바꾸었을 때 다음 오류가 발생했습니다.
AssertionError: 'basename' 인수가 지정되지 않았으며 '.queryset' 특성이 없기 때문에 뷰 세트에서 이름을 자동으로 확인할 수 없습니다.
그래서 당연히 저는 urls.py 에 가서 다음과 같은 기본 이름을 포함하도록 등록을 수정했습니다.
router.register(r'messages', MessageViewSet, basename='messages')
하지만 그 후 저는 다음과 같은 오류를 겪었습니다(원래 게시물에서 볼 수 있음).
보기 이름 "message-detail"을 사용하여 하이퍼링크 관계의 URL을 확인할 수 없습니다.API에 관련 모델을 포함하지 못했거나 이 필드에서 'lookup_field' 특성을 잘못 구성했을 수 있습니다.
라우터에서 DRF 문서를 읽은 후 라우터가 자동으로 두 개의 URL 패턴을 생성한다는 것을 알게 되었습니다. 이 패턴은 다음과 같습니다.
- 'basname-list'
- 'basname-interval'
기본 이름='syslog'(마지막에 's' 참고)를 설정했기 때문에 URL 패턴의 이름은 다음과 같습니다.
- '선택 목록'
- '1989-1989'
DRF가 'message-detail'이라는 URL 패턴을 찾고 있었기 때문에(여기에는 's'가 없음을 참고하십시오), 단순히 내 기본 이름에서 뒤에 오는 's'를 제거하면 다음과 같이 이 문제를 해결할 수 있다는 것을 깨달았습니다.
router.register(r'messages', MessageViewSet, basename='message')
최종 serializer 및 ViewSet 구현은 이렇게 간단했습니다!
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(...)
는 것 같습니다.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
이게 도움이 되길 바랍니다.
오류는 같지만 이유는 다릅니다.
사용자 지정 사용자 모델을 정의합니다. 새 필드는 없습니다.
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
내가주않때았문에기지때문▁i에'▁givet▁since▁didn기았내.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
.
일반 보기를 확장하는 경우클래스에서 모델 믹스를 설정하고 목록 보기에 URL 필드를 추가할 때 동일한 오류가 발생합니다. 이는 세부 보기를 정의하지 않기 때문입니다.RetrieveModelMixin 믹스를 다음에서 확장해야 합니다.
class UserViewSet (mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
3에서는 조금늦만장지 3서는에상이.include
하지 namespace
를 app_name
에서 "" " " " " 를 하는 중입니다.include
는 그 .
if namespaces and not app_name:
....
선택되어 있습니다.그리고 여전히 소스 코드에서 app_name은 다음과 같습니다.
urlconf_module, app_name = arg
arg
의 첫 입니다.include
이것은 우리에게, 우리의include
는 " " "로 정의되어야 합니다.
include((app.urls, app_name), namespace='...')
예
프로젝트가 있다고 가정합니다.myproject
그고앱 도 있습니다.myapp
그런 다음 주소를 설정하려고 합니다.와 같이 .
나의 앱.앱
router.register('address', exampleviewset, basename='address')
나의 프로젝트.
path('api/v1/', include(('myapp.urls', 'myapp'), namespace='myapp')),
serializers.py
class AddressSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name="myapp:address-detail")
class Meta:
model = Address
fields = ('url',...)
보아하니, 우리는 사용할 수 없습니다.fields='__all__'
우리는 포함해야 합니다.url
필요한 나머지 필드를 명시적으로 나열합니다.
DRF Quickstart Guide 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에 무언가가 제대로 만들어지지 않은 것으로 의심했습니다.나는 내 devdb를 신경쓰지 않아서 삭제하고 실행했습니다../manage.py migrate
명령을 다시 한 번 실행하고, 슈퍼 사용자를 생성하고, /users를 검색하고, 오류가 사라졌습니다.
DRF와 DB를 구성하는 작업 순서에 문제가 있었습니다.
만약 당신이 sqlite를 사용하고 있고 새로운 DB로 변경하는 것을 테스트할 수 있다면, 당신의 모든 코드를 해부하기 전에 시도해 볼 가치가 있습니다.
병 = 직렬화기.기본 키 관련 필드(read_only=True)
read_only를 사용하면 모델의 다른 뷰에 연결하지 않고도 필드를 나타낼 수 있습니다.
데이터베이스에서 슬러그 값이 비어 있을 때(''와 동일) DRF 3.7.7에서 오류가 발생했습니다.
나는 이 같은 문제에 부딪혔고 추가하여 해결했습니다.generics.RetrieveAPIView
내 견해에 대한 기본 클래스로.
저는 거의 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')),
]
그리고 저는 마침내 제 문제를 해결했습니다. 그래서 누구나 그 이유를 알 수 있습니다. 최선을 다하죠.
serializer에서 'id'와 'url' 필드를 생략해도 문제가 없습니다.어차피 json 객체에 반환된 id를 사용하여 게시물에 액세스할 수 있기 때문에 프론트엔드 구현이 훨씬 쉬워집니다.
저도 같은 문제가 있었습니다. 당신이 확인해야 할 것 같습니다.
get_absolute_url
개체 모델의 메서드 입력 값(**kwargs) 제목입니다.lookup_field에서 정확한 필드 이름을 사용합니다.
주의할 점은 만약 당신이 다음을 만든다면.action
와 함께detail=False
(이합니다. (typo?)로 그러면 이 오류가 발생합니다. 다음으로 대체합니다.detail=True
:
@action(detail=True)
...
모든 것을 즉시 사용할 수 있도록 유지하고 싶어서 사용자 직렬화 도구를 추가했습니다.
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['id', 'username']
보기 집합:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
URL에 추가되었습니다.
router.register(r'users', UserViewSet)
DRF 문서에서:
참고: 하이퍼링크된 직렬화 프로그램에서 네임스페이스를 사용하는 경우 직렬화 프로그램의 view_name 매개 변수가 네임스페이스를 올바르게 반영하는지 확인해야 합니다.위의 예에서는 사용자 세부 정보 보기에 하이퍼링크된 직렬화 도구 필드에 view_name='app_name:user-properties'와 같은 매개 변수를 포함해야 합니다.
자동 view_name 생성은 %(model_name)-detail과 같은 패턴을 사용합니다.모델 이름이 실제로 충돌하지 않는 한 하이퍼링크된 직렬화 프로그램을 사용할 때 장고 REST Framework 보기의 이름 간격을 지정하지 않는 것이 좋습니다.
해결책
from rest_framework import serializers
from myapp.models import Post
from django.contrib.auth.models import User
class PostSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name="api:post-detail")
author = serializers.HyperlinkedRelatedField(view_name="api:user-detail", read_only=True)
viewers = serializers.HyperlinkedRelatedField(view_name="api:user-detail", read_only=True, many=True)
class Meta:
model = Post
fields = ('id', 'title', 'url', 'author', 'viewers')
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = "__all__"
언급URL : https://stackoverflow.com/questions/20550598/django-rest-framework-could-not-resolve-url-for-hyperlinked-relationship-using
'source' 카테고리의 다른 글
젠킨스에서 파이썬 유닛 테스트? (0) | 2023.07.16 |
---|---|
음의 시간 범위 형식 지정 (0) | 2023.07.16 |
xml 없이 Ehcache 3 + 스프링 부트 + Java 구성을 구성하려면 어떻게 해야 합니까? (0) | 2023.07.16 |
angular2 테스트를 위해 http 오류를 모의하는 방법 (0) | 2023.07.16 |
Oracle: 쿼리를 통해 전체 비율을 얻는 방법은 무엇입니까? (0) | 2023.07.16 |