问题描述
我有一个状态模型和一个用于为每种状态存储几种语言的模型:
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
模型上进行查询,则将返回Order
个对象的QuerySet。
假设有一个名为foo
的订单对象。这个foo
有一个状态,其状态有很多lang。那么您希望查询得到什么条件?
您在问题中提到的查询:Order.objects.filter(status__langs__lang='en')
说给我所有Order
,它们的状态至少包含一个lang='en'
。订单序列化程序包含状态序列化程序,状态序列化程序包含其所有lang。
为了要在序列化对象中显示一种特定的语言,应自定义序列化程序。像这样:
>>> 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
}
}
]
>>>
但这不是一个好方法;这只是一种简单的方法。