Django过滤查询,自动计算属性字段

时间:2015-07-27 16:47:48

标签: python django django-models

有Django Order模型,其中属性字段自动加密。如何进行过滤查询。

class Order(models.Model):

    @property
    def expire(self):
        return self.created + datetime.timedelta(days=self.days_left())

    @property
    def days_left(self):
        return self.recurrence_period  * self._recurrence_unit_days[self.recurrence_unit]

为了从今天起获得1,3,7个日期时间而进行的计算

settings.SUBSCRIPTION_EXPIRATION_REMIND = [1, 3, 7]

days = map(lambda x: datetime.date.today() + datetime.timedelta(days=x), settings.SUBSCRIPTION_EXPIRATION_REMIND)

[datetime.date(2015, 7, 28),
 datetime.date(2015, 7, 30),
 datetime.date(2015, 8, 3)]

如何按ORM查询过滤

Order.objects.filter(expire__in=days)

Django投掷错误。

FieldError: Cannot resolve keyword 'expire' into field.

3 个答案:

答案 0 :(得分:28)

不,您无法根据模型方法或属性执行查找。 Django ORM不允许这样做。

查询被编译为SQL以在数据库级别发送和处理,而属性是Python代码,数据库对它们一无所知。这就是为什么Django过滤器只允许我们使用数据库字段的原因。

可以这样做:

Order.objects.filter(created=..) # valid as 'created' is a model field

不能这样做:

Order.objects.filter(expires=..) # INVALID as 'expires' is a model property

您可以使用列表推导来获得所需的结果。

[obj for obj in Order.objects.all() if obj.expire in days]

以上内容将为我提供Order列表中expire个值为days的对象列表。

答案 1 :(得分:3)

我不认为您可以在字段查找中使用属性,因为文档说The field specified in a lookup has to be the name of a model field https://docs.djangoproject.com/en/1.8/topics/db/queries/#field-lookups

答案 2 :(得分:-6)

结束添加过期到模型,计算保存方法的值。现在我可以做到

 Order.objects.filter(expire__in=days)