我需要使用queryset中的ManyToMany过滤字段。必须仅保留活动的产品
class Product(model.Model):
name = models.CharField()
active = models.BooleanField(blank=True, default=True)
class Package(model.Model):
name = models.CharField()
products = models.ManyToManyField(Product)
我尝试过类似的事情。
packages = Package.objects.all()
for package in packages:
active_products = package.products.filter(active=True)
package.products = active_products
但是当我只需要更改查询集时,它将更新数据库中的包。
期望概念(实际上不需要嵌套结构,查询集就可以了):
packages = [
{'id': 1, 'name': 'First package', 'products': [
{'id': 1, 'name': 'first product', 'active': True},
{'id': 2, 'name': 'second product', 'active': True},
]},
{'id': 2, 'name': 'Second package', 'products': [
{'id': 2, 'name': 'first product', 'active': True},
{'id': 3, 'name': 'third product', 'active': True},
]},
{'id': 3, 'name': 'Third package', 'products': []}
]
我考虑过要通过 .values()从“包”中创建字典列表,然后对其进行迭代并排除所有未激活的产品。 您知道更优雅的方式吗?
答案 0 :(得分:1)
AFAIK,您不会从Django获得 嵌套输出 :(但是您会得到与 类似的 QuerySet 类的> .values()
方法为
results = Package.objects.filter(products__active=True).values('id', 'name', 'products__id', 'products__name', 'products__active')
filtered_result = [result for result in results if result['products__active']]
答案 1 :(得分:1)
我不确定这是否行得通。但是我认为我们可以使用serializers.MethodSerialier
进行游戏。如果失败,我们可以尝试返回其他内容,而不是直接返回Productserializer
。
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('id', 'name')
class PackageSerializer(serializers.ModelSerializer):
products = serializers.MethodSerializer()
class Meta:
model = Package
fields = ('id', 'name', 'products')
def get_products(self, obj):
products = obj.products.filter(active=True)
return ProductSerializer(products, many=True)
packages = Package.objects.filter(products__active=True)
serializer = PackageSerializer(packages, many=True)
# do something with the serializer