Django Rest Framework - Could not resolve URL for hyperlinked relationship using view name “user-detail”

前端 未结 17 1238
感动是毒
感动是毒 2020-11-28 03:11

I am building a project in Django Rest Framework where users can login to view their wine cellar. My ModelViewSets were working just fine and all of a sudden I get this frus

相关标签:
17条回答
  • 2020-11-28 03:43

    I had the same problem , I think you should check your

    get_absolute_url

    object model's method input value (**kwargs) title. and use exact field name in lookup_field

    0 讨论(0)
  • 2020-11-28 03:44

    Another nasty mistake that causes this error is having the base_name unnecessarily defined in your urls.py. For example:

    router.register(r'{pathname}', views.{ViewName}ViewSet, base_name='pathname')
    

    This will cause the error noted above. Get that base_name outta there and get back to a working API. The code below would fix the error. Hooray!

    router.register(r'{pathname}', views.{ViewName}ViewSet)
    

    However, you probably didn't just arbitrarily add the base_name, you might have done it because you defined a custom def get_queryset() for the View and so Django mandates that you add the base_name. In this case you'll need to explicitly define the 'url' as a HyperlinkedIdentityField for the serializer in question. Notice we are defining this HyperlinkedIdentityField ON THE SERIALIZER of the view that is throwing the error. If my error were "Could not resolve URL for hyperlinked relationship using view name "study-detail". You may have failed to include the related model in your API, or incorrectly configured the lookup_field attribute on this field." I could fix this with the following code.

    My ModelViewSet (the custom get_queryset is why I had to add the base_name to the router.register() in the first place):

    class StudyViewSet(viewsets.ModelViewSet):
        serializer_class = StudySerializer
    
        '''custom get_queryset'''
        def get_queryset(self):
            queryset = Study.objects.all()
            return queryset
    

    My router registration for this ModelViewSet in urls.py:

    router.register(r'studies', views.StudyViewSet, base_name='studies')
    

    AND HERE'S WHERE THE MONEY IS! Then I could solve it like so:

    class StudySerializer(serializers.HyperlinkedModelSerializer):
        url = serializers.HyperlinkedIdentityField(view_name="studies-detail")
        class Meta:
            model = Study
            fields = ('url', 'name', 'active', 'created',
                  'time_zone', 'user', 'surveys')
    

    Yep. You have to explicitly define this HyperlinkedIdentityField on itself for it to work. And you need to make sure that the view_name defined on the HyperlinkedIdentityField is the same as you defined on the base_name in urls.py with a '-detail' added after it.

    0 讨论(0)
  • 2020-11-28 03:46

    I came across this error too and solved it as follows:

    The reason is I forgot giving "**-detail" (view_name, e.g.: user-detail) a namespace. So, Django Rest Framework could not find that view.

    There is one app in my project, suppose that my project name is myproject, and the app name is myapp.

    There is two urls.py file, one is myproject/urls.py and the other is myapp/urls.py. I give the app a namespace in myproject/urls.py, just like:

    url(r'', include(myapp.urls, namespace="myapp")),
    

    I registered the rest framework routers in myapp/urls.py, and then got this error.

    My solution was to provide url with namespace explicitly:

    class UserSerializer(serializers.HyperlinkedModelSerializer):
        url = serializers.HyperlinkedIdentityField(view_name="myapp:user-detail")
    
        class Meta:
            model = User
            fields = ('url', 'username')
    

    And it solved my problem.

    0 讨论(0)
  • 2020-11-28 03:48

    Because it's a HyperlinkedModelSerializer your serializer is trying to resolve the URL for the related User on your Bottle.
    As you don't have the user detail view it can't do this. Hence the exception.

    1. Would not just registering the UserViewSet with the router solve your issue?
    2. You could define the user field on your BottleSerializer to explicitly use the UserSerializer rather than trying to resolve the URL. See the serializer docs on dealing with nested objects for that.
    0 讨论(0)
  • 2020-11-28 03:49

    Maybe someone can have a look at this : http://www.django-rest-framework.org/api-guide/routers/

    If using namespacing with hyperlinked serializers you'll also need to ensure that any view_name parameters on the serializers correctly reflect the namespace. For example:

    urlpatterns = [
        url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
        url(r'^api/', include(router.urls, namespace='api')),
    ]
    

    you'd need to include a parameter such as view_name='api:user-detail' for serializer fields hyperlinked to the user detail view.

    class UserSerializer(serializers.HyperlinkedModelSerializer):
        url = serializers.HyperlinkedIdentityField(view_name="api:user-detail")
    
    class Meta:
        model = User
        fields = ('url', 'username')
    
    0 讨论(0)
  • 2020-11-28 03:49

    Same Error, but different reason:

    I define a custom user model, nothing new field:

    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
    

    This is my view function:

    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
    

    Since I didn't give queryset directly in UserViewSet, I have to set base_name when I register this viewset. This is where my error message caused by 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'
    

    You need a base_name same as your model name - customuser.

    0 讨论(0)
提交回复
热议问题