創建自定義的Concat
註釋,它將模仿MySQL
GROUP_CONCAT
函數。然後,您可以在註釋bindings
上使用.values
。
Django的1.8您的Concat
類可以是這樣的:
from django.db import models
class Concat(models.Aggregate):
# supports GROUP_CONCAT(DISTINCT field SEPARATOR str_val)
# do not support order_by
function = 'GROUP_CONCAT'
template = '%(function)s(%(distinct)s%(expressions)s SEPARATOR "%(separator)s")'
def __init__(self, expression, distinct=False, separator=None, **extra):
super(Concat, self).__init__(
expression,
distinct='DISTINCT ' if distinct else '',
separator=separator or '',
output_field=models.CharField(),
**extra)
雖然Django 1.7
class Concat(models.Aggregate):
def add_to_query(self, query, alias, col, source, is_summary):
#we send source=CharField to prevent Django from casting string to int
aggregate = SQLConcat(col, source=models.CharField(), is_summary=is_summary, **self.extra)
query.aggregates[alias] = aggregate
#for mysql
class SQLConcat(models.sql.aggregates.Aggregate):
sql_function = 'group_concat'
@property
def sql_template(self):
if self.extra.get('separator'):
return '%(function)s(%(field)s SEPARATOR "%(separator)s")'
else:
return '%(function)s(%(field)s)'
現在你可以這樣做:
Author.objects.annotate(bindings=Concat('book__edition__binding')).values('name', 'bindings')
不幸的是這不會篩選books
by cycle__id=3
,bu您可以在註釋發生之前應用過濾器。
Author.objects.filter(book__cycle__id=3).annotate(bindings=Concat('book__edition__binding')).values('name', 'bindings')
這將從結果authors
剝離而不book
與cycle__id=3
。