如何在drf-nested-routers中包括嵌套资源的超链接以应用Hateoas原理?
上下文
我在Django REST框架中具有以下嵌套资源的API
/wizard-api/industries/
/wizard-api/industries/<pk>/
/wizard-api/industries/<industry_pk>/sub-industries/
/wizard-api/industries/<industry_pk>/sub-industries/<pk>/
/wizard-api/industries/<industry_pk>/sub-industries/<sub_industry_pk>/details/
/wizard-api/industries/<industry_pk>/sub-industries/<sub_industry_pk>/details/<pk>/
# basenames:
wizard-api:industries-list
wizard-api:industries-detail
wizard-api:sub-industries-list
wizard-api:sub-industries-detail
wizard-api:details-list
wizard-api:details-detail
,我的URL使用 drf-nested-routers :
# Nested Routes
first_level = routers.SimpleRouter()
first_level.register(r'industries', views.IndustryViewSet, basename='industries')
second_level = routers.NestedSimpleRouter(first_level, r'industries', lookup='industry')
second_level.register(r'sub-industries', views.SubIndustryViewSet, basename='sub-industries')
third_level = routers.NestedSimpleRouter(second_level, r'sub-industries', lookup='sub_industry')
third_level.register(r'details', views.SubIndustryDetailsViewSet, basename='abc')
erd
我想应用 hateoas 原理
# endpoint: /wizard-api/industries/1/
# response:
{
"id": 1,
"name": "food and beverage",
"subindustries": "http://127.0.0.1:8000/wizard-api/industries/1/sub-industries/"
}
中实现了第一级,
class IndustryModelSerializer(serializers.ModelSerializer):
subindustries = serializers.HyperlinkedIdentityField(
view_name='wizard-api:sub-industries-list',
lookup_url_kwarg='industry_pk'
)
class Meta:
model = Industry
exclude = ['created', 'modified', 'active']
我使用 hyper -hyprinbedidentityfieldfield 在第一个序列化器问题
当我尝试在后续级别应用相同的逻辑时出现问题,即:从子工业级别 详细信息级别:
/wizard-api/industries/<industry_pk>/sub-industries/<sub_industry_pk>/details/
我尝试使用第二级序列化的详细信息字段(子工业):
class SubIndustryModelSerializer(serializers.ModelSerializer):
details = serializers.HyperlinkedIdentityField(
view_name='wizard-api:details-list',
lookup_url_kwarg='industry_pk'
)
class Meta:
model = SubIndustry
exclude = ['created', 'modified', 'active']
预期的
预期响应是:
# endpoint: /wizard-api/industries/1/sub-industries/
# response:
[
{
"id": 1,
"name": "beverage industries",
"details": "http://127.0.0.1:8000/wizard-api/industries/1/sub-industries/1/details/"
},
{
"id": 2,
"name": "food production",
"details": "http://127.0.0.1:8000/wizard-api/industries/1/sub-industries/2/details/"
}
]
错误
,但我有以下错误:
无法使用视图名称解决超链接关系的URL “向导-API:详细信息列表”。您可能未能包括相关的 API中的模型,或错误地配置了
lookup_field
该字段上的属性。
Context
I have an API in Django REST framework with the following nested resources
/wizard-api/industries/
/wizard-api/industries/<pk>/
/wizard-api/industries/<industry_pk>/sub-industries/
/wizard-api/industries/<industry_pk>/sub-industries/<pk>/
/wizard-api/industries/<industry_pk>/sub-industries/<sub_industry_pk>/details/
/wizard-api/industries/<industry_pk>/sub-industries/<sub_industry_pk>/details/<pk>/
# basenames:
wizard-api:industries-list
wizard-api:industries-detail
wizard-api:sub-industries-list
wizard-api:sub-industries-detail
wizard-api:details-list
wizard-api:details-detail
Here my URLs config using drf-nested-routers:
# Nested Routes
first_level = routers.SimpleRouter()
first_level.register(r'industries', views.IndustryViewSet, basename='industries')
second_level = routers.NestedSimpleRouter(first_level, r'industries', lookup='industry')
second_level.register(r'sub-industries', views.SubIndustryViewSet, basename='sub-industries')
third_level = routers.NestedSimpleRouter(second_level, r'sub-industries', lookup='sub_industry')
third_level.register(r'details', views.SubIndustryDetailsViewSet, basename='abc')
ERD
I want to apply the HATEOAS principle
# endpoint: /wizard-api/industries/1/
# response:
{
"id": 1,
"name": "food and beverage",
"subindustries": "http://127.0.0.1:8000/wizard-api/industries/1/sub-industries/"
}
I made it for the first level using the HyperlinkedIdentityField in the first Serializer
class IndustryModelSerializer(serializers.ModelSerializer):
subindustries = serializers.HyperlinkedIdentityField(
view_name='wizard-api:sub-industries-list',
lookup_url_kwarg='industry_pk'
)
class Meta:
model = Industry
exclude = ['created', 'modified', 'active']
Problem
The problem appears when I try to apply the same logic in the subsequent levels, i.e: generating the url from the sub-industries level to the details level:
/wizard-api/industries/<industry_pk>/sub-industries/<sub_industry_pk>/details/
I tried with the details field in the serializer of the second level (sub-industries):
class SubIndustryModelSerializer(serializers.ModelSerializer):
details = serializers.HyperlinkedIdentityField(
view_name='wizard-api:details-list',
lookup_url_kwarg='industry_pk'
)
class Meta:
model = SubIndustry
exclude = ['created', 'modified', 'active']
Expected
The expected response is:
# endpoint: /wizard-api/industries/1/sub-industries/
# response:
[
{
"id": 1,
"name": "beverage industries",
"details": "http://127.0.0.1:8000/wizard-api/industries/1/sub-industries/1/details/"
},
{
"id": 2,
"name": "food production",
"details": "http://127.0.0.1:8000/wizard-api/industries/1/sub-industries/2/details/"
}
]
Error
But I got the following error:
Could not resolve URL for hyperlinked relationship using view name
"wizard-api:details-list". You may have failed to include the related
model in your API, or incorrectly configured thelookup_field
attribute on this field.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我做了一些测试并找到了解决方案。
首先,在您的情况下,实现嵌套路线的最佳方法是使用这些超链接式modelializer , nestedhyhyperlinkedmodelserialializer 。
因此,第一个级别应该看起来像这样:
第二层中的主要问题可以像这样解决:
基于您的ERD,您必须包含一个parent_kwargs,以适当地配置嵌套路由,更改 dubl 对于字段,并添加URL参数。
希望它有效!
I made some tests and found the solution.
First, the best way to implement the nested routes in your case will be with these HyperlinkedModelSerializer, NestedHyperlinkedModelSerializer.
So the first level should look like this:
The main problem in the second level can be fixed like this:
Based on your ERD, you must include a parent_kwargs for the proper configuration of nested routes, change the exclude for fields, and add the url parameter.
Hope it works!