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()
移到末尾。如果你让它工作编辑工作线到这个答案请。