Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django QuerySet带子查询的注释_Python_Sql_Django_Database_Sqlite - Fatal编程技术网

Python Django QuerySet带子查询的注释

Python Django QuerySet带子查询的注释,python,sql,django,database,sqlite,Python,Sql,Django,Database,Sqlite,给定以下模型 class Pizza(Model): pass class Topping(Model): on = ManyToMany(Pizza, related_name='on_pizza') 我正在试着得到我的比萨饼和配料的数量,以及前三名的其他比萨饼(配料数量最多) 最终结果应该是: 包含当前比萨和前3个比萨的列表,以及所有比萨的配料数量 所以现在我有一个披萨, 我有排名前三的比萨饼(从配料数量来看,排在前三位) 但我必须重复上面的比萨饼来创建一个dict for pi

给定以下模型

class Pizza(Model):
  pass

class Topping(Model):
  on = ManyToMany(Pizza, related_name='on_pizza')
我正在试着得到我的比萨饼和配料的数量,以及前三名的其他比萨饼(配料数量最多) 最终结果应该是: 包含当前比萨和前3个比萨的列表,以及所有比萨的配料数量

所以现在我有一个披萨, 我有排名前三的比萨饼(从配料数量来看,排在前三位)

但我必须重复上面的比萨饼来创建一个dict

for pizza in top_pizzas:
  data.append({'pizza':pizza, 'num':pizza.tcount})
您可以创建一个用于构造两个查询集的uion。因此,这是:

def compared_with_top(self):
    top = Pizza.objects.exclude(pk=self.pk).annotate(
        tcount=Count('on_pizza')
    ).order_by('-tcount')
    pizzas = Pizza.objects.filter(pk=self.pk).annotate(
        tcount=Count('on_pizza')
    ).union(top[:3])
def已将_与_顶部(自身)进行比较:
top=Pizza.objects.exclude(pk=self.pk).注释(
t计数=计数('on_pizza')
).order_by('-t帐户')
pizzas=Pizza.objects.filter(pk=self.pk).注释(
t计数=计数('on_pizza')
).union(前[:3])

@ReedJones:测试过这个。如果在上运行此操作,则会出现错误。可能对于其他数据库,这将正常运行。

如果这些是您的比萨饼:

Pizza.objects.values()
Out[15]: <QuerySet [
    {'id': 1, 'name': 'Hawaiian'},
    {'id': 2, 'name': 'Cheese'},
    {'id': 3, 'name': 'Veggie'},
    {'id': 4, 'name': 'Meat Lovers'},
    {'id': 5, 'name': 'Pineapple ONLY'}
]>
每个比萨饼的配料数量是多少:

In [32]: Pizza.objects.annotate(Count('toppings')).values()
Out[32]: <QuerySet [
{'id': 1, 'name': 'Hawaiian', 'toppings__count': 2},
{'id': 2, 'name': 'Cheese', 'toppings__count': 1},
{'id': 3, 'name': 'Veggie', 'toppings__count': 5},
{'id': 4, 'name': 'Meat Lovers', 'toppings__count': 6},
{'id': 5, 'name': 'Pineapple ONLY', 'toppings__count': 1}
]>
Pizza。根据计数结果将\u与\u top进行比较

In [26]: hawaiian.compared_with_top()
Out[26]: <QuerySet [<Pizza: Hawaiian>, <Pizza: Cheese>, <Pizza: Veggie>, <Pizza: Meat Lovers>]>

In [27]: cheese.compared_with_top()
Out[27]: <QuerySet [<Pizza: Cheese>, <Pizza: Hawaiian>, <Pizza: Veggie>, <Pizza: Meat Lovers>]>

In [28]: veggie.compared_with_top()
Out[28]: <QuerySet [<Pizza: Veggie>, <Pizza: Hawaiian>, <Pizza: Cheese>, <Pizza: Meat Lovers>]>

In [29]: meat.compared_with_top()
Out[29]: <QuerySet [<Pizza: Meat Lovers>, <Pizza: Hawaiian>, <Pizza: Cheese>, <Pizza: Veggie>]>

In [30]: pineapple.compared_with_top()
Out[30]: <QuerySet [<Pizza: Pineapple ONLY>, <Pizza: Hawaiian>, <Pizza: Veggie>, <Pizza: Meat Lovers>]>
[26]中的
:夏威夷语。将_与_top()进行比较
出[26]:
在[27]中:cheese.将_与_top()进行比较
出[27]:
在[28]中:素食者。将_与_top()进行比较
出[28]:
在[29]中:肉类。将_与_top()进行比较
出[29]:
在[30]中:菠萝。将_与_top()进行比较
出[30]:

这将获得正确的输出,queryset中的第一个对象是当前pizza。不过,接下来的三个问题并不是从最重要到最次要的。它是向后的。我不知道为什么他们被分为最差到最差,但也许其他人知道。我怀疑这是因为使用了
Q

我还不完全清楚你想要什么。你能提供一些示例场景和预期结果吗?我添加了一些解释,基本上是从一个模型实例,我想得到一个查询集,其中包含当前比萨及其浇头数量,以及前三名其他比萨及其浇头数量,但你订购的比萨有浇头数量吗?我只是想确定一下,因为我觉得排序有点奇怪。是的,排名前三位的比萨饼是按排名前三位的比萨饼。想象一个问题,有很多评论,我想要当前的问题,它的评论数,与评论最多的前三位问题相比,all-in-1查询似乎是正确的,但这会给出一个错误:在复合语句的子查询中不允许ORDER BY。注意:上述错误仅在sqlite@ReedJones:更新了一个注释。通过将查询集与“|”组合,我最终使用了与上述类似的解决方案
Topping.objects.all()
Out[17]: <QuerySet [
    <Topping: Canadian Bacon>, <Topping: Pineapple>, <Topping: Cheese>,
    <Topping: Green peppers>, <Topping: Olives>, <Topping: Mushrooms>,
    <Topping: Onions>, <Topping: Tomatoes>, <Topping: Sausage>,
    <Topping: Pepperoni>, <Topping: Beef>
]>
from django.db import models
from django.db.models import Q, Count

class Pizza(models.Model):
    name = models.CharField(max_length=50)
    toppings = models.ManyToManyField('Topping', related_name='on_pizza')

    def __str__(self):
        return self.name

    def compared_with_top(self):
        top = Pizza.objects.annotate(Count('toppings')).order_by(
            '-toppings__count').exclude(id=self.id)[:3]
        return Pizza.objects.filter(Q(id=self.id) | Q(id__in=top.values('id')))
        

class Topping(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name
In [32]: Pizza.objects.annotate(Count('toppings')).values()
Out[32]: <QuerySet [
{'id': 1, 'name': 'Hawaiian', 'toppings__count': 2},
{'id': 2, 'name': 'Cheese', 'toppings__count': 1},
{'id': 3, 'name': 'Veggie', 'toppings__count': 5},
{'id': 4, 'name': 'Meat Lovers', 'toppings__count': 6},
{'id': 5, 'name': 'Pineapple ONLY', 'toppings__count': 1}
]>
hawaiian = Pizza.objects.get(name='Hawaiian')
cheese = Pizza.objects.get(name='Cheese')
veggie = Pizza.objects.get(name='Veggie')
meat = Pizza.objects.get(name='Meat Lovers')
pineapple = Pizza.objects.get(name='Pineapple ONLY')
In [26]: hawaiian.compared_with_top()
Out[26]: <QuerySet [<Pizza: Hawaiian>, <Pizza: Cheese>, <Pizza: Veggie>, <Pizza: Meat Lovers>]>

In [27]: cheese.compared_with_top()
Out[27]: <QuerySet [<Pizza: Cheese>, <Pizza: Hawaiian>, <Pizza: Veggie>, <Pizza: Meat Lovers>]>

In [28]: veggie.compared_with_top()
Out[28]: <QuerySet [<Pizza: Veggie>, <Pizza: Hawaiian>, <Pizza: Cheese>, <Pizza: Meat Lovers>]>

In [29]: meat.compared_with_top()
Out[29]: <QuerySet [<Pizza: Meat Lovers>, <Pizza: Hawaiian>, <Pizza: Cheese>, <Pizza: Veggie>]>

In [30]: pineapple.compared_with_top()
Out[30]: <QuerySet [<Pizza: Pineapple ONLY>, <Pizza: Hawaiian>, <Pizza: Veggie>, <Pizza: Meat Lovers>]>