Как вызвать имя поля модели django из списка?

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

как мы называем имя поля из списка?

1 ответ

Решение

Вот item интерпретируется как идентификатор, поэтому имя параметра item, То, что существует переменная с таким же именем и определенным значением, не имеет значения.

Однако мы можем это исправить, создав словарь, который отображает item (поэтому здесь он будет заменен на соответствующее значение) True, False, а также None, Мы можем использовать этот словарь в качестве словаря именованных параметров *, используя две последовательные звездочки в качестве префикса:

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, Falseс и Nones. Мы можем фактически расширить эту логику и даже посчитать все в одном запросе, который обычно более эффективен (это само по себе не так, но выполнение запроса обычно приводит к дополнительным затратам на создание запроса, интерпретируя запрос на стороне базы данных)., сериализация результатов и т. д.).

Другие вопросы по тегам