【发布时间】:2018-03-11 05:11:29
【问题描述】:
我正在尝试使用 drf-nested-routes 包在序列化程序中生成嵌套的 HATEOAS 链接。我当前的设置如下:
/resource_a/<pk>
/resource_a/<pk>/resource_b/<pk>
/resource_a/<pk>/resource_b/<pk>
/resource_a/<pk>/resource_b/<pk>/resource_c
我无法创建指向最后一条路线的HyperlinkedIdentityField。根据文档,可以像这样创建超链接字段:
nameservers = HyperlinkedIdentityField(
view_name='domain-nameservers-list',
lookup_url_kwarg='domain_pk'
)
或者
nameservers = NestedHyperlinkedRelatedField(
many=True,
read_only=True, # Or add a queryset
view_name='domain-nameservers-detail'
parent_lookup_url_kwargs={'domain_pk': 'domain__pk'}
)
但是,当尝试访问 URL 层次结构中 2 层深处的资源时,这些方法会失败。第一种方法不兼容,因为它不允许添加第二个lookup_url_kwarg,而对于第二种方法,在使用(在我看来)适当的属性(@987654330)进行配置时会引发异常(ImproperlyConfigured) @, resource_b__pk)。
这个包有可能吗?否则,我将使用SerializerMethodField 使用更简单的解决方案:
resource_c = serializers.SerializerMethodField()
def get_resource_c(self, obj):
url = reverse('resource_b-resource_c-list', kwargs=dict(resource_a_pk=obj.resource_a.pk, resource_b_pk=obj.pk))
return self.context['request'].build_absolute_uri(url)
提前致谢!
【问题讨论】:
-
根据我的经验,当您像
/resource_a/<pk>/resource_b/<pk>/resource_c这样注册您的网址并且您想在reverse通话中使用它时会出现问题。您是否在您的网址中复制了<pk>标记? -
我没有像那样注册 URL,这是生成的 API 方案。我基本上按照docs中的例子
-
您能否添加一个真实的示例,因为查看
NestedHyperlinkedRelatedField的源代码,您可以看到它正在执行一些字符串拆分等github.com/alanjds/drf-nested-routers/blob/…。所以当这种情况发生时,调试一个真实的例子会更容易。 -
@martinarroyo 我在使用
NestedHyperlinkedRelatedField之前已经这样做了,它确实有效。我的猜测是您的配置不正确。我注意到的一件事是您使用parent_lookup_url_kwargs,而在我的情况下我使用parent_lookup_kwargs。根据您的解释,我认为它需要看起来像这样NestedHyperlinkedRelatedField(..., parent_lookup_kwargs={'resource_a_pk': '<how to reach resource a pk from resource b>'})。 -
谢谢@vignesh 做到了。不过,文档提到了
parent_lookup_url_kwargs参数。我刚刚传递了这些参数:view_name='resource-c-list', parent_lookup_kwargs={'resource_a_pk': 'a__pk'}, lookup_url_kwarg='b_pk'。随意添加您的评论作为答案,以便我可以将问题标记为已关闭。
标签: django django-rest-framework drf-nested-routers