首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >DRF无法使用PrimaryKeyRelatedField上的视图名称解析超链接关系的URL

DRF无法使用PrimaryKeyRelatedField上的视图名称解析超链接关系的URL
EN

Stack Overflow用户
提问于 2020-12-25 00:02:03
回答 1查看 438关注 0票数 2

我在DRF序列化程序上遇到了一个令人沮丧的问题--由于某种原因,DRF转到了一个错误的视图名称,并且view_namePrimaryKeyRelated Field上不是一个可设置的属性。

型号:

代码语言:javascript
运行
复制
# (the class with the issue)
class Section(models.Model):
    teacher = models.ManyToManyField(Teacher)

# (a class that works, using the same pattern)
class Assessment(models.Model):
    standards = models.ManyToManyField(Standard)

序列化程序:

代码语言:javascript
运行
复制
# (doesn't work)
class SectionInfoSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name="gbook:section-detail")
    teacher = serializers.PrimaryKeyRelatedField(many=True, read_only=True),
    teachers_id = serializers.PrimaryKeyRelatedField(write_only=True, queryset=Teacher.objects.all(), many=True, source='teacher', allow_empty=False)

    class Meta:
        model = Section
        fields = '__all__'
        read_only_fields = ['sendEmails', 'teacher', 'course']

# (works)
class AssessmentSerializer(serializers.HyperlinkedModelSerializer):
    pk = serializers.PrimaryKeyRelatedField(read_only=True)
    url = serializers.HyperlinkedIdentityField(view_name="appname:assessments-detail")
    standards = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
    standards_id = serializers.PrimaryKeyRelatedField(queryset=Standard.objects.all(), source='standards', write_only=True, many=True, allow_empty=False)

    class Meta:
        model = Assessment
        fields = '__all__'

urls:

代码语言:javascript
运行
复制
router.register(r'teachers', teacher_views.TeacherViewSet, basename='teacher')
router.register(r'sections', course_views.SectionViewSet)
router.register(r'standards', gbook.views.standard_views.StandardViewSet, basename='standards')
router.register(r'assessments', AssessmentViewSet, basename='assessments')

我在POST和PUT过程中使用了_id字段来发送相关obejct的id,然后序列化它们。这在AssessmentSerializer (和其他几个)上工作得很好,但失败的原因我搞不懂。当然,在错误中返回的视图中缺少appname,但我不知道为什么会发生这种情况,以及为什么以前没有发生这种情况。

堆栈跟踪:

代码语言:javascript
运行
复制
Internal Server Error: /appname/sections/
Traceback (most recent call last):
  File "/venv2/lib/python3.8/site-packages/rest_framework/relations.py", line 393, in to_representation
    url = self.get_url(value, self.view_name, request, format)
  File "/venv2/lib/python3.8/site-packages/rest_framework/relations.py", line 331, in get_url
    return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
  File "/venv2/lib/python3.8/site-packages/rest_framework/reverse.py", line 47, in reverse
    url = _reverse(viewname, args, kwargs, request, format, **extra)
  File "/venv2/lib/python3.8/site-packages/rest_framework/reverse.py", line 60, in _reverse
    url = django_reverse(viewname, args=args, kwargs=kwargs, **extra)
  File "/venv2/lib/python3.8/site-packages/django/urls/base.py", line 87, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "/venv2/lib/python3.8/site-packages/django/urls/resolvers.py", line 685, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'teacher-detail' not found. 'teacher-detail' is not a valid view function or pattern name.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/lib/python3.8/site-packages/rest_framework/viewsets.py", line 114, in view
    return self.dispatch(request, *args, **kwargs)
  File "/lib/python3.8/site-packages/rest_framework/views.py", line 505, in dispatch
    response = self.handle_exception(exc)
  File "/lib/python3.8/site-packages/rest_framework/views.py", line 465, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/lib/python3.8/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
    raise exc
  File "/lib/python3.8/site-packages/rest_framework/views.py", line 502, in dispatch
    response = handler(request, *args, **kwargs)
  File "/lib/python3.8/site-packages/rest_framework/mixins.py", line 20, in create
    headers = self.get_success_headers(serializer.data)
  File "/lib/python3.8/site-packages/rest_framework/serializers.py", line 562, in data
    ret = super().data
  File "/lib/python3.8/site-packages/rest_framework/serializers.py", line 260, in data
    self._data = self.to_representation(self.instance)
  File "/lib/python3.8/site-packages/rest_framework/serializers.py", line 529, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "/lib/python3.8/site-packages/rest_framework/relations.py", line 533, in to_representation
    return [
  File "/lib/python3.8/site-packages/rest_framework/relations.py", line 534, in <listcomp>
    self.child_relation.to_representation(value)
  File "/lib/python3.8/site-packages/rest_framework/relations.py", line 408, in to_representation
    raise ImproperlyConfigured(msg % self.view_name)
django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "teacher-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
[24/Dec/2020 09:55:04] "POST /appname/sections/ HTTP/1.1" 500 157269
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-25 01:32:57

所以,我遗漏的是这些是HyperlinkedModelSerializer。评估的不同之处在于您如何处理ManyToMany。

一个HyperlinkedModelSerializer,为相关字段生成HyperlinkedRelatedField,并从rest_framework.utils.get_detail_view_name生成view_name,它没有用于应用程序名称的工具。

这是由build_field完成的,它根据从rest_framework.utils.model_meta.get_field_info()获得的模型信息将任务委托给build_relational_field

您的teacher字段可能就在那里。

我不确定为什么它适用于评估,因为我也找不到拒绝/接受的条件,但我的直觉告诉我,因为PrimaryKeyRelatedField是一个相关的字段,所以它不会构建HyperlinkedRelatedField。

无论采用哪种方法,您都应该看到传递给build_relational_field的字段名是什么/哪些字段名才能解决这个问题。

解决方案

删除teacher字段定义后面的逗号:

代码语言:javascript
运行
复制
teacher = serializers.PrimaryKeyRelatedField(many=True, read_only=True),
                                                                 ------^

这会将teacher变成一个元组,teachers_id也会消失。结果,创建了标准的超链接相关字段:

代码语言:javascript
运行
复制
SectionInfoSerializer(instance=<Section: Section object (1)>):
    url = HyperlinkedIdentityField(view_name='gbook:section-detail')
    teachers_id = PrimaryKeyRelatedField(allow_empty=False, many=True, queryset=<QuerySet [<Teacher: Teacher object (1)>]>, source='teacher', write_only=True)
    send_emails = BooleanField(required=False)
    teacher = HyperlinkedRelatedField(allow_empty=False, many=True, read_only=True, view_name='teacher-detail')
    course = HyperlinkedRelatedField(allow_empty=False, many=True, read_only=True, view_name='course-detail')
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65440636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档