Dav*_*ull 17 django django-rest-framework
我试图实现一个嵌套资源,其中一个字段依赖于其父资源的值.
假设我们正在为一家公司建立一个系统,该系统提供有关其客户的信息以及该公司销售人员的销售数据.所以我们有两个模型,Customer和Rep.代表可以向多个客户出售.
返回所有客户的URL: /api/1.0/customers/
特定客户的URL: /api/1.0/customers/123/
特定销售代表的客户特定信息的URL: /api/1.0/customers/123/rep/9/
请注意,rep URL包含客户ID和代表ID.
我希望客户URL返回一个嵌套资源,其中包含有关代表的摘要信息,以及指向该代表的完整客户特定信息的超链接.这是所有客户的URL输出:
[
{
"id": 100,
"customer_name": "DolManSaxLil",
"rep": {
"id": 4,
"annual_sales": 1500.01,
"name": "Fred",
"url": "http://localhost:8000/api/1.0/customer/100/rep/4/"
}
},
{
"id": 200,
"customer_name": "Hotblack",
"rep": {
"id": 4,
"annual_sales": 10500.42,
"name": "Fred",
"url": "http://localhost:8000/api/1.0/customer/200/rep/4/"
}
}
]
Run Code Online (Sandbox Code Playgroud)
为实现这一点,我们定义了两个序列化器
class CustomerSummarySerializer(serializers.HyperlinkedModelSerializer):
id = ...
name = ...
rep = RepSummarySerializer(read_only=True)
class RepSummarySerializer(serializers.HyperlinkedModelSerializer):
id = ...
annual_sales = ...
name = ....
url = serializers.SerializerMethodField('get_rep_url')
Run Code Online (Sandbox Code Playgroud)
我面临的问题是我无法弄清楚如何从函数中访问当前的customer.id RepSummarySerializer.get_rep_url
. 在详细信息视图中可以将客户保留在self.parent.obj
:
def get_rep_url(self, obj):
customer_id = self.parent.obj.id
url = reverse('api_customer_rep',
kwargs={'customer_id': customer_id,
'rep_id': obj.id},
request=serializer.context.get('request'))
return url
Run Code Online (Sandbox Code Playgroud)
但是,在列表视图中,self.parent.obj
是Customer对象的QuerySet,我看不到任何识别当前Customer的方法.有没有办法做到这一点?我错过了一些明显的事吗?
Dav*_*ull 20
清晰的时刻:解决方案是使用a SerializerMethodField
实例化RepSummarySerializer
并传递customer_id
上下文:
class CustomerSummarySerializer(serializers.HyperlinkedModelSerializer):
id = ...
name = ...
rep = serializers.SerializerMethodField('get_rep')
def get_rep(self, obj):
rep = obj.rep
serializer_context = {'request': self.context.get('request'),
'customer_id': obj.id}
serializer = RepSummarySerializer(rep, context=serializer_context)
return serializer.data
Run Code Online (Sandbox Code Playgroud)
在customer_id
现在可以访问在RepSummarySerializer.get_rep_url
像这样的:
def get_rep_url(self, obj):
customer_id = self.context.get('customer_id')
...
Run Code Online (Sandbox Code Playgroud)
不知道为什么我三小时前没想到这个.
归档时间: |
|
查看次数: |
4293 次 |
最近记录: |