class Ingredient(Model):
name = CharField(max_length=55, unique=True)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
class Product(Model):
name = CharField(max_length=55)
def __str__(self):
return self.name
class Meta:
ordering = ('name', )
class ProductIngredient(Model):
product = ForeignKey(Product, on_delete=CASCADE, related_name='product_ingredients')
ingredient = ForeignKey(Ingredient, on_delete=CASCADE)
optional = BooleanField(default=False)
class Meta:
unique_together = (('product', 'ingredient'),)
ordering = ('product__name',)
def __str__(self):
return f'{self.product} - {self.ingredient}'
我想做两个查询:
- 选择所有成分含有草莓和牛奶的产品
- 选择所有成分含有草莓或牛奶的产品
第一个查询是:Product.objects.prefetch_related('product_ingredients__ingredient').filter(product__ingredients__ingredient__name='strawberry').filter(product__ingredients__ingredient__name='milk')
我需要在第一个查询中写入distinct
吗? 如何编写第二个查询?
我需要在第一个查询中写不同的吗?
不,或者至少不是,如果product
-ingredient
组合是唯一的,就像这里一样。这将是不同的,因为这两种成分是明显不同的。此外,您不应在此处使用.prefetch_related(..)
,除非您确实想使用相关的Ingredient
来渲染Product
。所以写就足够了:
Product.objects.filter(
product__ingredients__ingredient__name='strawberry'
).filter(
product__ingredients__ingredient__name='milk'
)
如何编写第二个查询?
您可以使用__in
查找 [Django-doc] 进行过滤:
Product.objects.filter(
product__ingredients__ingredient__name__in=['strawberry', 'milk']
)
使用 Q 对象进行复杂查找
Product.objects.prefetch_related('product_ingredients__ingredient').filter(Q(product__ingredients__ingredient__name='strawberry')|Q(product__ingredients__ingredient__name='milk'))