使用以下型号:
class Item(models.Model):
name = models.CharField(max_length=255)
attributes = models.ManyToManyField(ItemAttribute)
class ItemAttribute(models.Model):
attribute = models.CharField(max_length=255)
string_value = models.CharField(max_length=255)
int_value = models.IntegerField()
我还有一个Item
,它有2个属性,'color': 'red'
和'size': 3
。
如果我执行以下任何查询:
Item.objects.filter(attributes__string_value='red')
Item.objects.filter(attributes__int_value=3)
我会返回Item
,按预期工作。
但是,如果我尝试进行多重查询,例如:
Item.objects.filter(attributes__string_value='red', attributes__int_value=3)
我想做的只是一个AND。这也不起作用:
Item.objects.filter(Q(attributes__string_value='red') & Q(attributes__int_value=3))
输出结果为:
<QuerySet []>
为什么呢?如何构建此类查询以返回Item
,因为它具有属性red
和属性3
?
答案 0 :(得分:2)
如果有任何用处,可以在Django中链接过滤表达式:
query = Item.objects.filter(attributes__string_value='red').filter(attributes__int_value=3')
来自DOCS:
这将获取数据库中所有条目的初始QuerySet,添加过滤器,然后是排除,然后是另一个过滤器。最终结果是一个QuerySet,其中包含标题以“What”开头的所有条目,这些条目是在2005年1月30日和当天之间发布的。
使用.filter()
但使用动态参数:
args = {
'{0}__{1}'.format('attributes', 'string_value'): 'red',
'{0}__{1}'.format('attributes', 'int_value'): 3
}
Product.objects.filter(**args)
您可以 (如果您需要混合使用AND
和OR
)使用Django&#39; s Q objects。
关键字参数查询 - 在filter()等中 - 与“AND”编辑在一起。如果需要执行更复杂的查询(例如,带OR语句的查询),则可以使用Q对象。
Q对象(django.db.models.Q)是用于封装a的对象 关键字参数的集合。指定了这些关键字参数 如上面的“字段查找”。
你会有这样的东西,而不是在那个过滤器中拥有所有Q objects
:
** import Q from django
from *models import Item
#assuming your arguments are kwargs
final_q_expression = Q(kwargs[1])
for arg in kwargs[2:..]
final_q_expression = final_q_expression & Q(arg);
result = Item.objects.filter(final_q_expression)
这是我无法运行的代码,它已经脱离了我的头脑。如果愿意,可将其视为伪代码。
尽管如此,这并不能解释为什么你尝试过的方式不起作用。也许它与跨越关系的查找以及正在加入以获取这些值的表有关。我建议您打印yourQuerySet.query
以显示正在形成的raw SQL
,这可能有助于指导您.filter( Q() & Q())
无效的原因。