首页 > 解决方案 > 如何否定 django 中的查询集函数?

问题描述

我在 django 3.1 中有这个查询集

class AuthenticationQuerySet(InheritanceQuerySet):
    def expired(self):
        return self.filter(
            date_created__lt=timezone.localtime() - self.model.ACTIVE_THRESHOLD
        )

    def active(self):
        return self.filter(status__in=["PENDING"]).exclude(
            date_created__lt=timezone.localtime() - self.model.ACTIVE_THRESHOLD
        )

请注意,我使用了相同的条件,但在排除函数中。我这样做是因为我想不出更简单的解决方案。但感觉应该有一种方法可以否定查询集函数过滤的内容?

我想象的和感觉更自然的东西是

class AuthenticationQuerySet(InheritanceQuerySet):
    def expired(self):
        return self.filter(
            date_created__lt=timezone.localtime() - self.model.ACTIVE_THRESHOLD
        )

    def active(self):
        return self.filter(status__in=["PENDING"]).exclude(self.expired)

这样的事情可能吗?

还是我应该选择类似的东西:

class AuthenticationQuerySet(InheritanceQuerySet):
    def expired(self):
        return self.filter(self._expired_condition)
    
    def active(self):
        return self.filter(status__in=["PENDING"]).exclude(self._expired_condition)
    
    @property
    def _expired_condition(self):
        return Q(date_created__lt=timezone.localtime() - self.model.ACTIVE_THRESHOLD)

? 但这似乎真的很丑陋和hacky......

也许在一些简单的条件下,我应该选择第一个解决方案,而最后一个解决方案应该使用一些非常复杂的解决方案?

感谢您的建议!

编辑:我更改了第一个示例以使其更加明显,我不是在寻找排除功能。

标签: djangodjango-queryset

解决方案


You can use expired queryset in active method:

def active(self):
        return self.filter(status__in=["PENDING"])
                   .exclude(pk__in=self.expired().values_list('pk', flat=True))

Or you can define a custom Lookup __expired for date_created field and then use it in expired and active methods "date_created__expired". Docs.


推荐阅读