3
我有這個運行良好的ORM查詢。我測試了以下看到輸出,並將其作爲實際預期:將靜態CASE WHEN語句轉換爲動態以提供給.annotate()
members=Members.objects.all().annotate(age_groups=Case(
When(birthdate__year__range=(2007,2017), then=Value('0-10')),
When(birthdate__year__range=(1997,2006), then=Value('11-20')),
When(birthdate__year__range=(1987,1996), then=Value('21-30')),
When(birthdate__year__range=(1977,1986), then=Value('31-40')),
When(birthdate__year__range=(1967,1976), then=Value('41-50')),
When(birthdate__year__range=(1957,1966), then=Value('51-60')),
When(birthdate__year__range=(1947,1956), then=Value('61-70')),
When(birthdate__year__range=(1937,1946), then=Value('71-80')),
When(birthdate__year__range=(1927,1936), then=Value('81-90')),
When(birthdate__year__range=(1917,1926), then=Value('91-100')),
default=Value('100+'), output_field=CharField())
).values('age_groups',).annotate(total=Count('age_groups'))
但我想將它移動到一個功能,使用戶可以指定要使用的日期字段,並做分組他們喜歡(如0-20,21-40等)。爲此,我編寫了下面的函數,它在調用時只輸出CASE WHEN statements
作爲字符串。問題是當我通過它annotate()
我得到str
有no resolve error
。
希望你得到我想要做的。我需要下面的函數的輸出傳遞到annoate()
:
from datetime import date
def AgeGrouping(field_name,required_min_age=0,required_max_age=100,jump_by=10):
now_year=date.today().year
reply='Case('
just_started=True
for i in range(now_year-required_min_age,now_year-required_max_age,-jump_by):
if just_started==False:
min_age=max_age + 1
max_age=min_age + 9
else:
min_age= now_year - i
max_age= min_age + 10
min_year=now_year- min_age
max_year= now_year - max_age
reply="\n".join([reply,"When(" + field_name + "__year__range=(" + str(max_year) + "," + str(min_year) + "), then=Value('" + str(min_age) + "-" + str(max_age) + "')),"])
just_started=False
reply="\n".join([reply, "default=Value('100+'), output_field=models.CharField())"])
return reply
然後調用它像這樣:
print(AgeGrouping('birthdate',required_min_age=0,required_max_age=100,jump_by=10))
感謝@Alasdair ......都按預期非常好。 –