为什么Django REST Framework的HyperlinkedModelSerializer不能形成URL?

时间:2015-10-18 18:15:30

标签: django django-rest-framework

DRF新手,只要我在字段中不包含'url',一切都有效。这就是我所拥有的:

串行:

class TaskSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Task
        fields = ('pk', 'short_desc', 'scheduled_date')

查看集:

class TaskViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Task.objects.all().order_by('scheduled_date')
    serializer_class = TaskSerializer

网址:

router = routers.DefaultRouter()
router.register(r'tasks', views.TaskViewSet)

urlpatterns = [

    [... bunch of non-REST URLs]

    # REST API
    url(r'^', include(router.urls)),

在运行时,打印router.urls给了我:

<RegexURLPattern api-root ^$>
<RegexURLPattern api-root ^\.(?P<format>[a-z0-9]+)/?$>
<RegexURLPattern task-list ^tasks/$>
<RegexURLPattern task-list ^tasks\.(?P<format>[a-z0-9]+)/?$>
<RegexURLPattern task-detail ^tasks/(?P<pk>[^/.]+)/$>
<RegexURLPattern task-detail ^tasks/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>

如果我在浏览器中输入[...]/tasks/[...]/tasks/123/,它们就会起作用,这让我相信任务列表和任务详细信息视图确实存在。

现在我通过在序列化程序中添加'url'来引入一个问题:

class TaskSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Task
        fields = ('url', 'pk', 'short_desc', 'scheduled_date')

将“url”添加到字段后,出现以下错误:

  

无法使用视图名称解析超链接关系的URL   “任务详情”。您可能未能在其中包含相关模型   您的API,或者lookup_field属性配置不正确   这个领域。

DRF文件说:

  

需要有一种方法来确定应该使用哪些视图   超链接到模型实例。默认情况下,预期超链接   对应于与样式'{model_name} -detail'匹配的视图名称,   并通过pk关键字参数查找实例。

由于我已经验证了任务详细信息的存在以及相应的URL [...]/tasks/123/是否有效,因此我无法终身了解为什么DRF无法形成URL。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

受到Kunkka的回答所揭示的线索的启发,我有一个看起来像这样的解决方案:

class TaskSerializer(serializers.HyperlinkedModelSerializer):

    url = serializers.HyperlinkedIdentityField(view_name="task:task-detail")

    class Meta:
        model = Task
        fields = ('url', 'pk', 'short_desc', 'scheduled_date')

即。我在我的问题中最初发布的序列化程序中添加了url = [...]行。这解决了查找问题,这可能是由于DRF不知道“任务详细信息”而引起的。实际上是在&#39;任务&#39;命名空间。

有更好的解决方案吗?

答案 1 :(得分:2)

你能试试吗?

class TaskSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.SerializerMethodField()
    class Meta:
        model = Task
        fields = ('pk','url', 'short_desc', 'scheduled_date')

    def get_url(self,obj):
        request = self.context['request']
        return = {'self':reverse('task-detail',kwargs={'pk':obj.pk},request=request)}