在Django中使用条件注释时出错:select_format

时间:2018-06-10 20:43:57

标签: mysql django

在尝试注释查询集时,我从django方法中获取了一个TypeError。 我在Ubuntu上使用Django 1.11.12和MySQL 5.7.22。

这是我的models.py:

class Group(models.Model):
    name = models.CharField(max_length=100)

class ActivationRecord(models.Model):
    group = models.ForeignKey('directory.Group')
    year = models.PositiveIntegerField()

一个群体是活跃的"如果它有给定年份的记录。我尝试使用以下查询来注释组是否处于活动状态:

Group.objects.annotate(active=Case(
    When(activationrecord__year=2018, then=True), default=False, output_field=BooleanField))

当我运行时,我收到以下错误:

  File "/home/vagrant/Envs/think/lib/python3.5/site-packages/django/db/models/query.py", line 226, in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
  File "/home/vagrant/Envs/think/lib/python3.5/site-packages/django/db/models/query.py", line 250, in __iter__
    self._fetch_all()
  File "/home/vagrant/Envs/think/lib/python3.5/site-packages/django/db/models/query.py", line 1118, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/home/vagrant/Envs/think/lib/python3.5/site-packages/django/db/models/query.py", line 53, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch)
  File "/home/vagrant/Envs/think/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 877, in execute_sql
    sql, params = self.as_sql()
  File "/home/vagrant/Envs/think/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 429, in as_sql
    extra_select, order_by, group_by = self.pre_sql_setup()
  File "/home/vagrant/Envs/think/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 46, in pre_sql_setup
    self.setup_query()
  File "/home/vagrant/Envs/think/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 37, in setup_query
    self.select, self.klass_info, self.annotation_col_map = self.get_select()
  File "/home/vagrant/Envs/think/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 227, in get_select
    sql, params = self.compile(col, select_format=True)
  File "/home/vagrant/Envs/think/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 375, in compile
    return node.output_field.select_format(self, sql, params)
TypeError: select_format() missing 1 required positional argument: 'params'

2 个答案:

答案 0 :(得分:3)

需要使用BooleanField

()作为函数调用

Group.objects.annotate(active=Case(
    When(activationrecord__year=2018, then=True), 
default=False, output_field=BooleanField()))

答案 1 :(得分:1)

@Lemayzeur's answer确实解决了这个问题。

另一种方法可能是使用Exists子查询:

from django.db.models import Exists, OuterRef

Group.objects.annotate(
    active=Exists(
        ActivationRecord.objects.filter(year=2018, group=OuterRef('pk'))
    )
)

这基本上映射到SQL查询:

SELECT `group`.*, EXISTS(
    SELECT U0.*
    FROM `activationrecord` U0
    WHERE (U0.`group` = (`group`.pk)
           AND U0.`year` = 2018)
    ) AS `active`
FROM `group`