使用 django ORM 进行高级选择
Posted
技术标签:
【中文标题】使用 django ORM 进行高级选择【英文标题】:Advanced select with django ORM 【发布时间】:2015-07-15 04:53:18 【问题描述】:我正在使用以下模型:
class Topping(models.Model):
name = models.CharField(max_length=30)
class Pizza(models.Model):
name = models.CharField(max_length=50)
toppings = models.ManyToManyField(Topping)
def __str__(self): # __unicode__ on Python 2
return "%s (%s)" % (self.name, ", ".join(topping.name
for topping in self.toppings.all()))
现在我只想要素食菜单的元素,用西红柿过滤
pizza_item = Pizza.objects.filter(toppings__name='tomatoes')
我的选择是:
SELECT `pizza`.`id`, `pizza`.`name`
FROM `pizza`
INNER JOIN `pizza_toppings` ON (
`pizza`.`id` = `pizza_toppings`.`pizza_id` )
INNER JOIN `web_topping` ON (
`pizza_toppings`.`topping_id` = `topping`.`id` )
WHERE `topping`.`name` = azucar
但我想得到:
SELECT `pizza`.`id`, `pizza`.`name`, `topping`.`name`
FROM `pizza`
INNER JOIN `pizza_toppings` ON (
`pizza`.`id` = `pizza_toppings`.`pizza_id` )
INNER JOIN `web_topping` ON (
`pizza_toppings`.`topping_id` = `topping`.`id` )
WHERE `topping`.`name` = azucar
最后一个查询在 mysql db 中运行良好。并且使用 Pizza.objects.raw 但我想使用 django ORM
是topping.name
的选择,我尝试使用prefetch_select('toppings')
。但我无法获得相同的选择。
【问题讨论】:
【参考方案1】:您是否尝试过对 Queryset 使用 values 方法?
类似:
pizza_item = Pizza.objects.filter(toppings__name='tomatoes').values("id", "name", "toppings__name")
【讨论】:
您能详细描述一下您的解决方案吗? 这工作正常但不返回查询集,只返回值。但是sql代码是完美的。 Pizza_item = ['toppings__name': u'tomatoes', 'id': 1L, 'name': u'pizztomato']【参考方案2】:我不确定这是否可行。因为当您使用 Pizza.objects... 时,您仅限于 Pizza 模型中的字段。由于 Pizza 模型不包含浇头的名称字段。您无法检索它。您只能检索 toppings 的 id 字段:
pizza_item = Pizza.objects.filter(toppings__name='tomatoes').values('id', 'name', 'toppings')
这将在 SELECT 中提供“toppings”。“topping_id”。
另外,既然你已经指定了 toppings__name='tomatoes,那么在这个查询集中所有的 toppings 的名字都会是西红柿,那么有 topping
.@987654323 有什么意义呢? @ 在你的结果中?
【讨论】:
如果我使用 toppings__name= 不是问题,但如果我尝试使用 toppings__icontains='to' 我想获取所有查询。并希望使用查询集和“聚合” topping.name 来获取查询集。如果我使用 valuesqueryset 需要将所有内容添加到查询中,并且将来无法轻松更改模型。但是谢谢你的帮助!! 好的,我明白你的意思了。您必须使用 prefetch_related 从其他模型中获取值。 Pizza.objects.whatever() 不会得到另一个模型的名称字段。以上是关于使用 django ORM 进行高级选择的主要内容,如果未能解决你的问题,请参考以下文章