首页 > 解决方案 > DRF:无法使用视图名称“tickettype-detail”解析超链接关系的 URL

问题描述

我们希望我们的用户能够为我们网站中的各种选择字段定义选项。这些选项将放在他们自己的表(模型)中。

对于 API,我们有“票证”模型。它有一个字段“type”,它是“TicketType”模型的 ForeignKey。

我收到此错误:

Could not resolve URL for hyperlinked relationship using view
name "tickettype-detail". You may have failed to include the
related model in your API, or incorrectly configured the
`lookup_field` attribute on this field.

如果我从 Ticket 模型中删除 type 字段,错误就会消失。我已经在网上阅读了很多关于此的帖子,并尝试了很多不同的方法,但到目前为止还无法修复它。

模型.py:

from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _


class Ticket(models.Model):
    summary = models.CharField(
        verbose_name=_('Summary'),
        max_length=255,
    )
    description = models.TextField(
        verbose_name=_('Description'),
        blank=True,
    )
    type = models.ForeignKey(
        'TicketType',
        verbose_name=_('Type'),
        on_delete=models.PROTECT,
    )
    ...other fields omitted...
    created = models.DateTimeField(
        verbose_name=_('Created'),
        default=timezone.now,
    )


class TicketType(models.Model):
    type = models.CharField(
        verbose_name=_('Type'),
        max_length=255,
    )

序列化程序.py

from rest_framework import serializers, permissions

from tickets.models import Ticket, TicketType


class TicketSerializer(serializers.HyperlinkedModelSerializer):

    url = serializers.HyperlinkedIdentityField(view_name="tickets:ticket-detail")
    permission_classes = (permissions.IsAuthenticated,)

    class Meta:
        model = Ticket
        fields = (
            'url',
            'id',
            'summary',
            'description',
            'type',
            ...other fields omitted...
            'created',
        )


class TicketTypeSerializer(serializers.HyperlinkedModelSerializer):

    url = serializers.HyperlinkedIdentityField(view_name="tickets:tickettype-detail")
    permission_classes = (permissions.IsAuthenticated,)

    class Meta:
        model = TicketType
        fields = (
            'url',
            'id',
            'type',
        )

视图.py

from rest_framework import permissions
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateAPIView

from tickets.models import Ticket, TicketType
from tickets.serializers import TicketSerializer, TicketTypeSerializer


class TicketList(ListCreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = Ticket.objects.all()
    serializer_class = TicketSerializer


class TicketDetail(RetrieveUpdateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = Ticket.objects.all()
    serializer_class = TicketSerializer


class TicketTypeList(ListCreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = TicketType.objects.all()
    serializer_class = TicketTypeSerializer


class TicketTypeDetail(RetrieveUpdateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = TicketType.objects.all()
    serializer_class = TicketTypeSerializer

我尝试的大多数事情都与在各个地方添加lookkup_field 有关,但我想我没有找到正确的组合。

编辑:忘记发布我的 urls.py。

网址.py

from django.urls import path
from tickets import views

app_name = 'tickets'

urlpatterns = [
    path('', views.TicketList.as_view(), name='ticket-list'),
    path('<int:pk>/', views.TicketDetail.as_view(), name='ticket-detail'),
    path('types/', views.TicketTypeList.as_view(), name='tickettype-list'),
    path('types/<int:pk>/', views.TicketTypeDetail.as_view(), name='tickettype-detail'),
]

标签: djangodjango-rest-framework

解决方案


解决了!

在这种情况下,似乎 DRF 在尝试“反转”以获取该字段的选项列表时没有提供完全限定的 view_name。

我将此添加到 TicketType 序列化程序中:

    type = serializers.HyperlinkedRelatedField(
        queryset=TicketType.objects.all(),
        required=True,
        view_name='tickets:tickettype-detail',
    )

对于 view_name,DRF 使用的是“tickettype-detail”。

然后我将它添加到 TicketType 模型中:

    def __str__(self):
        return self.type

推荐阅读