Python Django Rest Framework-无法使用“视图名称”解析超链接关系的URL;“用户详细信息”;

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

我正在Django Rest框架中构建一个项目,用户可以登录该项目查看他们的酒窖。 我的模型视图集工作得很好,突然出现了一个令人沮丧的错误:

无法使用视图名称“用户详细信息”解析超链接关系的URL。您可能未能将相关模型包括在API中,或者在此字段上错误配置了
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导入默认路由器
    路由器=默认路由器()
    
    如果扩展GenericViewSetListModelMixin类,并且在列表视图中添加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(...)