无法使用视图名称 (django-rest-framework) 解析超链接关系的 URL

Posted

技术标签:

【中文标题】无法使用视图名称 (django-rest-framework) 解析超链接关系的 URL【英文标题】:Could not resolve URL for hyperlinked relationship using view name ( django-rest-framework ) 【发布时间】:2018-06-29 19:50:26 【问题描述】:

问题:

我收到这样的错误。

在 /api/users/ 处配置不正确

无法使用视图名称解析超链接关系的 URL “用户详细信息”。您可能未能将相关模型包含在 您的 API,或者错误地配置了 lookup_field 属性 这个字段。

我读过这个post,但它没有用。

serializers.py

​​>
class UserSerializer(serializers.ModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='user-detail',
                                               lookup_field='profile')

    class Meta:
        model = User
        fields = ('id', 'username', 'first_name', 'last_name', 'url')


class UserProfileSerializer(serializers.ModelSerializer):
    user = serializers.ReadOnlyField(source='user.username')

    class Meta:
        model = UserProfile
        fields = "__all__"
        # user = serializers.ReadOnlyField(source='owner.username')

    def create(self, validated_data):
        pass

    def update(self, instance, validated_data):
        pass

urls.py

​​>
user_profile_list = UserProfileViewSet.as_view(
    'get': 'list',
    'post': 'create'
)
user_profile_detail = UserProfileViewSet.as_view(
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
)
user_list = UserViewSet.as_view(
    'get': 'list'
)
user_detail = UserViewSet.as_view(
    'get': 'retrieve'
)
user_profiles_detail = UserViewSet.as_view(
    'get': 'profile'
)

router = DefaultRouter()
router.register(r'userprofiles', views.UserProfileViewSet)
router.register(r'users', views.UserViewSet)

urlpatterns = [
    url(r'^', include(router.urls))
]

views.py

​​>
class UserProfileViewSet(viewsets.ModelViewSet):
    """
    This viewset automatically provides `list`, `create`, `retrieve`,
    `update` and `destroy` actions.
    """
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly,)
    pagination_class = LimitTenPagination

    @detail_route(renderer_classes=[renderers.JSONRenderer])
    def perform_create(self, serializer):
        serializer.save(user=self.request.user)


class UserViewSet(viewsets.ReadOnlyModelViewSet):
    """
    This viewset automatically provides `list` and `detail` actions
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer

来自我的 models.py 的片段

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')

我尝试了什么:

我尝试将user-detail 更改为api:user-detail(是的api 命名空间确实存在于主urls.py 文件中)

【问题讨论】:

我知道您希望在User 序列化程序中有一个字段指向其配置文件的 URL,对吗? 您是想让 url 指向用户详细信息视图还是用户个人资料详细信息视图? @JessamynSmith 我正试图将其提供给用户详细信息,这就是为什么我选择model 作为User 而不是UserProfile @dukebody 是的,就是这样 【参考方案1】:

    看文档,我相信你必须使用HyperLinkedRelatedField。另请参阅this related SO post。

    您在序列化器字段定义中混淆了参数。我认为应该是:

    class UserSerializer(serializers.ModelSerializer):
        url = serializers.HyperlinkedRelatedField(view_name='api:userprofile-detail',
                                                  source='profile')
    

编辑:

添加namespaceapi

【讨论】:

我发现这只有在我将字段命名为与模型中相同时才有效,例如:profile = serializers.HyperlinkedRelatedField(read_only=True, view_name='userprofiles-detail') @JessamynSmith 是的,这就是为什么需要添加命名空间【参考方案2】:

从您的HyperlinkedIdentityField 中删除lookup_filed 属性,因为您不需要它。

因此您的 serializer 类应该如下所示:

class UserSerializer(serializers.ModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='user-detail', source='profile',)

    class Meta:
        model = User
        fields = ('id', 'username', 'first_name', 'last_name', 'url')

属性lookup_filed仅在引用使用relationship-field/attribute作为主键而不是默认autoincrement的模型类时才需要。例如,如果您的模型类如下所示,则可以使用它:

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile', primary_key=True)

【讨论】:

【参考方案3】:

如果您正在扩展 GenericViewSet 和 ListModelMixin 类,并且在列表视图中添加 url 字段时遇到相同的错误,那是因为您没有定义详细视图。确保您正在扩展 RetrieveModelMixin mixin:

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

感谢 Rowinson Gallego 的回答

【讨论】:

以上是关于无法使用视图名称 (django-rest-framework) 解析超链接关系的 URL的主要内容,如果未能解决你的问题,请参考以下文章

无法使用视图名称 (django-rest-framework) 解析超链接关系的 URL

无法在 Spring Boot 中解析名称为“index”的视图

django.core.exceptions.ImproperlyConfigured:无法使用视图名称“用户详细信息”解析超链接关系的 URL

圣杯。无法解析名称为“grailsDispatcherServlet”的 servlet 中名称为“index”的视图

无法导入名称视图

Django 无法导入名称视图