Django-针对预回迁查询集进行注释?

Django-针对预回迁查询集进行注释?,django,Django,是否可以对预取查询进行注释/计数 我下面的初始查询是基于电路的,然后我意识到,如果一个站点没有任何电路,我就不会有一个“无”类别,该类别将显示一个站点已关闭 conn_data = Circuits.objects.all() \ .values('circuit_type__circuit_type') \ .exclude(active_link=False) \ .annotate(total=Count('circuit_type__circuit_type'))

是否可以对预取查询进行注释/计数

我下面的初始查询是基于电路的,然后我意识到,如果一个站点没有任何电路,我就不会有一个“无”类别,该类别将显示一个站点已关闭

conn_data = Circuits.objects.all() \
    .values('circuit_type__circuit_type') \
    .exclude(active_link=False) \
    .annotate(total=Count('circuit_type__circuit_type')) \
    .order_by('circuit_type__monitor_priority')
所以我改为查询站点并使用预回迁,它现在为任何没有活动链接的站点设置了一个空的circuits\u。是否有Django方法根据conn_数据中的电路集创建新的总计?我打算手动遍历所有站点并以这种方式添加总数,但我想知道是否有一种方法可以在QuerySet中实现这一点

我的最终结果应该是:

[
    {'circuit_type__circuit_type': 'Fibre', 'total': 63},
    {'circuit_type__circuit_type': 'DSL', 'total': 29},
    {'circuit_type__circuit_type': 'None', 'total': 2}
]
预回迁查询:

conn_data = SiteData.objects.prefetch_related(
                                Prefetch(
                                'circuits_set',
                                queryset=Circuits.objects.exclude(active_link=False).select_related('circuit_type'),
                                )
                        )

我认为这行不通。它是否应该起作用还有争议。让我们看看
prefetch\u related
的作用

返回一个查询集,该查询集将在单个批处理中自动检索每个指定查找的相关对象

所以这里发生的是两个查询被调度,两个列表被实现。然后,这些列表在内存中进行分区,并分组到正确的父记录中

Count()
annotate()
是数据库管理系统的指令,解析为SQL

Select Count(id) from conn_data
由于
注释
预取相关
的工作方式,我认为它们不太可能在一起玩得很好<代码>预取相关的只是一种方便。从实际的角度来看,运行两个单独的ORM查询并将它们分配给
SiteData
记录实际上是一回事。所以有点像

#Gets all Circuits counted and grouped by SiteData 

Circuits.objects.values('sitedata_id)'.exclude(active_link=False).select_related('circuit_type').annotate(Count('site_data_id'));

然后您只需循环查看您的
站点数据
记录并分配计数。

好的,我得到了我想要的结果,这可能是一种更好的方法,但它的效果永远不会降低:

from collections import Counter
import operator

class ConnData(object):
    def __init__(self, priority='', c_type='', count=0 ):
        self.priority = priority
        self.c_type = c_type
        self.count = count
    def __repr__(self):
        return '{} {}'.format(self.__class__.__name__, self.c_type)  
# get all the site data
conn_data = SiteData.objects.exclude(Q(site_type__site_type='Data Centre') | Q(site_type__site_type='Factory')) \
                    .prefetch_related(
                                Prefetch(
                                'circuits_set',
                                queryset=Circuits.objects.exclude(active_link=False).select_related('circuit_type'),
                                )
                        )
# create a list for the conns
conns = []
# add items to list of dictionaries with all required fields
for conn in conn_data:
    try:
        conn_type = conn.circuits_set.all()[0].circuit_type.circuit_type
        prioritiy = conn.circuits_set.all()[0].circuit_type.monitor_priority
        conns.append({'circuit_type' : conn_type, 'priority' : prioritiy})
    except:
        # create category for down sites
        conns.append({'circuit_type' : 'Down', 'priority' : 10})
# crate new list for class data
conn_counts = []
# create counter data
conn_count_data = Counter(((d['circuit_type'], d['priority']) for d in conns))
# loop through counter data and add classes to list
for val, count in conn_count_data.items():
    cc = ConnData()
    cc.priority = val[1]
    cc.c_type = val[0]
    cc.count = count
    conn_counts.append(cc)
# sort the classes by priority
conn_counts = sorted(conn_counts, key=operator.attrgetter('priority'))

如果我得到电路,那么这将排除没有任何活动链接的站点数据。我需要确定站点何时没有活动链接,但如果有意义的话,我不想在站点有活动链接的地方没有活动链接?任何不在该列表中但在完整的
SiteData
列表中的站点都没有活动链接。类型错误:无法在.values()或.values\u list()之后调用select\u related(),您可能必须将
values()
移到末尾。如果你让它工作编辑工作线到这个答案请。