我有一个模型Student
,其管理器StudentManager
如下所示。As属性通过在join_date
中添加college_duration
来给出最后一个日期。但是当我执行这个属性计算时,它工作得很好,但是对于StudentManager
,它给出了一个错误。如何编写管理器类,该类使用模型字段动态计算某些字段,并用于过滤记录
计算字段不在模型字段中。尽管如此,我还是希望将其作为筛选标准
class StudentManager(models.Manager):
def passed_students(self):
return self.filter(college_end_date__lt=timezone.now())
class Student(models.Model):
join_date = models.DateTimeField(auto_now_add=True)
college_duration = models.IntegerField(default=4)
objects = StudentManager()
@property
def college_end_date(self):
last_date = self.join_date + timezone.timedelta(days=self.college_duration)
return last_date
Django给出的错误。当我试图访问Student.objects.passed_students()
django.core.exceptions.FieldError: Cannot resolve keyword 'college_end_date' into field. Choices are: join_date, college_duration
通过使用QuerySet的^{} (Django Doc)方法
因为模型管理器(更准确地说,
QuerySet
)正在包装在数据库中所做的事情。您也可以将模型管理器作为高级数据库包装器调用但是,属性
college_end_date
仅在模型类中定义,数据库不知道它,因此会出现错误使用
annotate(...)
方法是正确的Django方法。作为旁注,复杂的属性逻辑不能用annotate(...)
方法重新创建在您的情况下,我会将} (Django Doc),因为它(对我)更有意义
college_duration
字段从IntegerField(...)
更改为^{稍后,更新您的经理和属性,如下所示:
注意:
DurationField(...)
将在PostgreSQL中按预期工作,此实现将在PSQL中按的方式工作。如果正在使用任何其他数据库,您可能会遇到问题。如果是这样,您可能需要有一个“数据库功能”,该功能在与特定数据库对应的日期时间和持续时间数据集上运行就我个人而言,我喜欢this solution
引用@Willem Van Olsem的评论:
您可以执行他共享的消息,也可以将其设置为自动计算的模型字段
现在您可以在数据库中搜索它
注意:这类事情最好从您知道要筛选的数据开始。如果您有预先存在的数据,则需要重新保存所有现有实例
问题
您正试图查询数据库中不存在的行。此外,Django ORM不将属性识别为要注册的字段
解决方案
对您的问题的直接回答是创建注释,随后可以从中查询注释。然而,我会重新考虑您为学生设计的表格,因为它引入了不必要的复杂性和维护开销
框架/db对开始日期和结束日期特性的支持比开始日期和时间增量多得多
在模型方法中存储结束日期并计算持续时间,而不是存储持续时间。这样做不仅更有意义,因为学生通常会得到一个开始日期和预计毕业日期,而不是持续时间,而且因为这样做会使类似的查询变得更容易
范例
询问2020年将毕业的学生
相关问题 更多 >
编程相关推荐