首页 > 解决方案 > django查询日期字段的年份未被提取

问题描述

在我的 django 项目中,我有两个模型 Person 和 Child。

class Person(models.Model):
    first_name = models.CharField('Name', max_length=200)
    family_name = models.ForeignKey(Family, on_delete=models.PROTECT)
    gender_is_male = models.BooleanField(default=True)

    birth_place = models.CharField(null=True, blank=True, max_length=200)
    year_of_birth = models.PositiveIntegerField(null=True, blank=True, validators=[MaxValueValidator(datetime.date.today().year), MinValueValidator(1800)])
    month_of_birth = models.PositiveIntegerField(null=True, blank=True, validators=[MaxValueValidator(12), MinValueValidator(1)])

    birth_date = models.DateField(null=True, blank=True) 

class Child(models.Model):
    person = models.OneToOneField(Person, on_delete=models.CASCADE, primary_key=True)
    father = models.ForeignKey(Person, on_delete=models.CASCADE, related_name='father_of', limit_choices_to={'gender_is_male': True})
    mother = models.ForeignKey(Person, on_delete=models.CASCADE, related_name='mother_of', limit_choices_to={'gender_is_male': False})

一个人可能有birth_date或只有year_of_birth和/或month_of_birth。我需要将孩子从大到小排序,并进行了以下查询:

children = person.mother_of.all().annotate(
                year_sort=Case(
                    When(
                        person__birth_date__isnull=False, then=('person__birth_date__year')
                    ),
                    default=('person__year_of_birth'),
                    output_field=PositiveIntegerField()
                )
            ).order_by('year_sort')

但我收到以下错误:

ValueError at /members/237/
invalid literal for int() with base 10: '1956-08-25'

当我回溯时,我看到了这个:

connection:<django.db.backends.sqlite3.base.DatabaseWrapper object at 0x7f0bd3264700>
converter:<function BaseExpression.convert_value.<locals>.<lambda> at 0x7f0bd1e76d30>
converters:[(3,
  ([<function BaseExpression.convert_value.<locals>.<lambda> at 0x7f0bd1e76d30>],
   <Case: CASE WHEN <WhereNode: (AND: <django.db.models.lookups.IsNull object at 0x7f0bd1f8d970>)> THEN Col(T3, members.Person.birth_date), ELSE Col(T3, members.Person.year_of_birth)>))]
convs:[<function BaseExpression.convert_value.<locals>.<lambda> at 0x7f0bd1e76d30>]
expression:<Case: CASE WHEN <WhereNode: (AND: <django.db.models.lookups.IsNull object at 0x7f0bd1f8d970>)> THEN Col(T3, members.Person.birth_date), ELSE Col(T3, members.Person.year_of_birth)>
pos:3
row:[266, 263, 237, '1956-08-25']
rows:<itertools.chain object at 0x7f0bd1e8f580>
self:<django.db.models.sql.compiler.SQLCompiler object at 0x7f0bd1e8f3d0>
value:'1956-08-25'

似乎表达式then=('person__birth_date__year')正在转换为THEN Col(T3, members.Person.birth_date)而不是THEN Col(T3, members.Person.birth_date.year)

我假设正确吗?我的代码有什么错误?

标签: pythondjangosqlitedjango-queryset

解决方案


推荐阅读