问题
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}'
I want to make two queries:
- select all products, whose ingredients contain strawberry AND milk
- select all products, whose ingredients contain strawberry OR milk
The first query is: Product.objects.prefetch_related('product_ingredients__ingredient').filter(product__ingredients__ingredient__name='strawberry').filter(product__ingredients__ingredient__name='milk')
Do I need to write distinct
in the first query?
How to write the second query?
回答1:
Do I need to write distinct in the first query?
No, or at least not if the product
-ingredient
combination is unique, like here. It will be distinct, since the two ingredients are clearly distinct. You furthermore should not use .prefetch_related(..)
here, unless you really want to render the Product
with the related Ingredient
s. So it is sufficient to write:
Product.objects.filter(
product__ingredients__ingredient__name='strawberry'
).filter(
product__ingredients__ingredient__name='milk'
)
How to write the second query?
You can filter with an __in lookup [Django-doc]:
Product.objects.filter(
product__ingredients__ingredient__name__in=['strawberry', 'milk']
)
回答2:
Use Q object for complex lookups
Product.objects.prefetch_related('product_ingredients__ingredient').filter(Q(product__ingredients__ingredient__name='strawberry')|Q(product__ingredients__ingredient__name='milk'))
来源:https://stackoverflow.com/questions/60225398/filter-intermediary-manytomany-django