django - 具有一对多唯一值的 Django Rest Framework 嵌套序列化程序
问题描述
我有一个用于状态的模型和一个用于为每种状态存储多种语言的模型:
class Status(models.Model):
code = models.IntegerField()
class StatusValueLang(models.Model):
status = models.ForeignKey(Status, related_name="langs", on_delete=models.CASCADE)
lang = models.CharField(max_length=3)
value = models.CharField(max_length=255)
我有一个模型使用状态
class Order(models.Model):
number = models.CharField(max_length=10)
status = models.ForeignKey(Status, on_delete=models.PROTECT)
然后,我想序列化这个查询集(获取带有英文状态名称的订单):
orders = Order.objects.filter(status__langs__lang='en')
使用序列化器。序列化器:
class StatusValueLangSerializer(serializers.Serializer):
value = serializers.CharField(max_length=255)
class StatusSerializer(serializers.Serializer):
langs = StatusValueLangSerializer(many=True)
class OrderSerializer(serializers.Serializer):
number = models.CharField(max_length=10)
status = StatusSerializer()
它可以工作,但是由于'langs = StatusValueLangSerializer(many = True)'行中的'Many = True',尽管我的过滤器(status__langs__lang ='en'),StatusSerializer仍返回所有行(语言)我如何设置序列化程序以获得此结果:
[
{
"number": "123",
"status": {
"langs": [
{
"value" : "Approved" <-- Just one, filtered row.
}
]
}
}
]
或者可能更好:
[
{
"number": "123",
"status": {
"value": "Approved"
}
}
]
解决方案
这与序列化程序无关。这是关于查询本身。如果您在模型上查询,将返回对象Order
的 QuerySet 。Order
假设有一个名为 的订单对象foo
。这foo
有一个状态,它的状态有很多语言。那么您对查询的期望是什么?
您在问题中提到的查询:Order.objects.filter(status__langs__lang='en')
说给我所有Order
s 他们的状态至少包含一个 s lang='en'
。订单序列化程序包含状态序列化程序,状态序列化程序包含其所有语言。
为了在序列化对象中显示一种特定语言,您应该自定义序列化程序。像这样的东西:
>>> class NewOrderSerializer(serializers.Serializer):
... number = serializers.CharField(max_length=10)
...
>>> desired_lang = 'en'
>>> desired_lang_value = StatusValueLang.objects.get(lang='en').value
>>> orders = Order.objects.filter(status__langs__lang=desired_lang)
>>> seriliazed_orders = NewOrderSerializer(orders, many=True)
>>> for order in seriliazed_orders:
... order['status'] = {'value': desired_lang}
...
>>> print(json.dumps(s, indent=4, sort_keys=True))
[
{
"number": "10001",
"status": {
"value": desired_lang_value
}
}
]
>>>
但这不是一个好方法;这只是一个简单的方法。
推荐阅读
- python - 查找必须使用两个节点列表中的任何两个节点的最短路径
- awk - 计算每个转录本的平均外显子数
- google-cloud-platform - 云 DNS 支持 mDNS
- c++ - C++值初始化向量迭代器比较
- asp.net-mvc - 连接到gluu服务器时,asp .net是否需要oxd服务器
- c++ - 在 Visual Studio 中从 Github 运行 C 代码
- xslt-1.0 - 在 XSLT 中添加两个科学数字
- python - 如何改进我的可视化图?观察点太近了
- nginx - 如果内容类型正确,如何将 nginx 配置为仅返回来自代理的响应?
- python - Python3 RLE 字符