如何从列表中调用django模型字段名称?

问题描述 投票:1回答:1

django models.py

class mymodel(models.Model):
   date_check   = models.DateField()
   item_1   = models.NullBooleanField()
   item_2   = mod`enter code here`els.NullBooleanField()
   item_3   = models.NullBooleanField()
   item_4   = models.NullBooleanField()
   item_5   = models.NullBooleanField()

任务:

>>> from .models import mymodel
>>> 
>>> a_list = ['item_1', 'item_2', 'item_3', 'item_4', 'item_5', 'item_5', ]
>>> a_year = 2018
>>> param1 = {}
>>> param2 = {}
>>> param3 = {}
>>> for item in a_list :
>>>    param1[item] = mymodel.objects.filter(date_check__year = a_year, item=True).count()
>>>    param2[item] = mymodel.objects.filter(date_check__year = a_year, item=False).count()
>>>    param3[item] = mymodel.objects.filter(date_check__year = a_year, item=None).count()
.....error here

我们如何从列表中调用字段名称?

python django models
1个回答
3
投票

这里item被解释为标识符,因此参数的名称是item。存在具有相同名称和特定值的变量的事实是不相关的。

然而,我们可以通过构建一个字典来解决这个问题,该字典将item(因此在这里它将被相应的值替换)映射到TrueFalseNone。我们可以使用这个字典作为命名参数字典*,使用两个连续的星号作为前缀:

for item in a_list :
    param1[item] = mymodel.objects.filter(date_check__year=a_year, **{item: True}).count()
    param2[item] = mymodel.objects.filter(date_check__year=a_year, **{item: False}).count()
    param3[item] = mymodel.objects.filter(date_check__year=a_year, **{item: None}).count()

请注意,这将导致多个查询。我们可以通过例如聚合选择来减少查询量,例如:

qs = mymodel.objects.filter(date_check__year=a_year)

for item in a_list :
    data = qs.aggregate(
        p1=Count('pk', filter=Q(**{item: True}))
        p2=Count('pk', filter=Q(**{item: False}))
        p3=Count('pk', filter=Q(**{item: None}))
    )
    param1[item] = data['p1'] or 0
    param2[item] = data['p2'] or 0
    param3[item] = data['p3'] or 0

因此,我们在每个查询中计算三件事:Trues,Falses和Nones的数量。我们实际上可以扩展这个逻辑,甚至可以计算单个查询中的所有内容,这通常更有效(这本身并不正确,但是进行查询通常会导致构造查询的一些开销,解释数据库端的查询,序列化结果等)。

© www.soinside.com 2019 - 2024. All rights reserved.