如何在Django的views.py中申请循环

How to apply for loop in Django's views.py

[research/models.py]

RECRUITING_CHOICES = [
    ('Recruiting', 'Recruiting'),
    ('Not yet recruiting', 'Not yet recruiting'),
    ('Completed', 'Completed'),
    ('Holding', 'Holding'),
]
RECRUITING_CHOICES_INV = {val: val for val, _ in RECRUITING_CHOICES}

class Research(models.Model):
    is_deleted = models.BooleanField(default=False)
    is_recruiting = models.CharField(choices=RECRUITING_CHOICES, null=True, max_length=50)
    research_name = models.CharField(max_length=2000, null=True)
    teacher= models.CharField(max_length=2000, null=True)

我正在使用 Django,我正在尝试使用 class 模型 'Research'.[=15= 在 views.py 中创建用于生成 apexchart(图形)的列表]

我正在尝试将 is_recruiting 字段的 4 个值中的每一个都添加到过滤中,但是添加 Recruiting 和 Not yet Recruiting 只需要多行代码并且使代码看起来效率低下。是否有使用 for 语句的解决方法?

[research/views.py]

counts = Research.objects.values('teacher') \
    .annotate(A=Count('id', filter=Q(type='A')),
              B=Count('id', filter=Q(type='B')),
              C=Count('id', filter=Q(type='C')),
              D=Count('id', filter=Q(type='D')),
              E=Count('id', filter=Q(type='E')),
              F=Count('id', filter=Q(type='F')),
              r_A=Count('id', filter=Q(type='A', is_recruiting='Recruiting')),
              r_B=Count('id', filter=Q(type='B', is_recruiting='Recruiting')),
              r_C=Count('id', filter=Q(type='C', is_recruiting='Recruiting')),
              r_D=Count('id', filter=Q(type='D', is_recruiting='Recruiting')),
              r_E=Count('id', filter=Q(type='E', is_recruiting='Recruiting')),
              r_F=Count('id', filter=Q(type='F', is_recruiting='Recruiting')),
              N_A=Count('id', filter=Q(type='A', is_recruiting='Not yet recruiting')),
              N_B=Count('id', filter=Q(type='B', is_recruiting='Not yet recruiting')),
              N_C=Count('id', filter=Q(type='C', is_recruiting='Not yet recruiting')),
              N_D=Count('id', filter=Q(type='D', is_recruiting='Not yet recruiting')),
              N_E=Count('id', filter=Q(type='E', is_recruiting='Not yet recruiting')),
              N_F=Count('id', filter=Q(type='F', is_recruiting='Not yet recruiting'))) \
    .values('teacher', 'A', 'B', 'C', 'D', 'E', 'F',
            'r_A', 'r_B', 'r_C', 'r_D', 'r_E', 'r_F',
            'N_A', 'N_B', 'N_C', 'N_D', 'N_E', 'N_F')

--------------------添加-------------------- ------ [views.py - 添加]

teacher = [];
A= [];
B= [];
C= [];
D= [];
E= [];
F= [];
r_A = [];
r_B = [];
r_C = [];
r_D = [];
r_E = [];
r_F = [];
for count in counts:
    teacher.append(str(count['teacher']))
    A.append(str(count['A']))
    B.append(str(count['B']))
    C.append(str(count['C']))
    D.append(str(count['D']))
    E.append(str(count['E']))
    Ftc.append(str(count['F']))
    r_A.append(str(count['r_A']))
    r_B.append(str(count['r_B']))
    r_C.append(str(count['r_C']))
    r_D.append(str(count['r_D']))
    r_E.append(str(count['r_E']))
    r_F.append(str(count['r_F']))

is_recruiting = request.GET.get('is_recruiting')

[graph.html]

<script>
    var options3 = {
    series: [{% if is_recruiting == 'Recruiting' %}
    {
      name: 'A',
      data: {{ r_A | safe }}
    }, {
      name: 'B',
      data: {{ r_B | safe }}
    }, {
      name: 'C',
      data: {{ r_C | safe }}
    }, {
      name: 'D',
      data: {{ r_D | safe }}
    }, {
      name: 'E',
      data: {{ r_E | safe }}
    }, {
      name: 'F',
      data: {{ r_F | safe }}
    },{% elif is_recruiting == 'ALL' %}
    {
      name: 'A',
      data: {{ A | safe }}
    }, {
      name: 'B',
      data: {{ B | safe }}
    }, {
      name: 'C',
      data: {{ C | safe }}
    }, {
      name: 'D',
      data: {{ D | safe }}
    }, {
      name: 'E',
      data: {{ E | safe }}
    }, {
      name: 'F',
      data: {{ F | safe }}
    },{% endif %}
    ],
</script>

我是否必须在 JavaScript 部分一遍又一遍地列出 if 语句?

您可以通过创建参数字典并在使用 ** 传递它时解压缩该字典来为函数构建动态关键字参数。

遍历您的类型,并为每个类型创建您想要的每个注解的键和值。

您还可以使用 *

将您创建的动态注释解压到字段名称中以传递给 values()
annotations = {}
types = ('A', 'B', 'C', 'D', 'E', 'F')
for type in types:
    annotations[type] = Count('id', filter=Q(type=type))
    annotations[f'r_{type}'] = Count('id', filter=Q(type=type, is_recruiting='Recruiting'))
    annotations[f'N_{type}'] = Count('id', filter=Q(type=type, is_recruiting='Not yet recruiting'))
counts = Research.objects.values('teacher').annotate(**annotations).values('teacher', *annotations.keys())

Kwargs 可以作为 dict 传递,因此您需要做的就是使用这些键:值对创建一个 dict。

你可以这样做:

recruiting_values = (
    ("", dict()),
    ("r_", dict(is_recruting="Recruiting")),
    ("n_", dict(is_recruting="Not"),
)
types = ("A", "B", "C")

...

.annotate(**{
    f"{prefix}{type}": Count("id", filter=Q(type=type, **recruiting)) for prefix, recruiting in recruiting_value for type in types
})