使用django或postgresql缓存问题

Run*_*oop 1 python django postgresql

我有一个问题,我的生产服务器显示错误的查询结果(正确考虑了创建和删除,但没有影响结果的现有字段的更新).我认为这是一个日期比较问题,并花了几个小时调试,因为我无法重现dev上的错误.最终,我重新启动了gunicorn,问题消失了.似乎postgresql或django都缓存了查询集结果.我没有设置缓存,所以不明白为什么会这样.

我有2个问题请:

  1. 谁在做缓存?
  2. 我该如何禁用它? - 我需要在每次调用时对queryset进行评估

建立

Python 2.7

Django 1.7

PostgreSQL的

Ubuntu的

views.py提取

class EventList(ListView, FilterMixin):
    model = Listing
    queryset = Listing.events.order_by('-from_date', )
Run Code Online (Sandbox Code Playgroud)

models.py提取

class Listing(models.Model):
    title = models.CharField(max_length=200, null=True)
    to_date = models.DateTimeField(null=True, blank=True)
    from_date = models.DateTimeField(null=True, blank=True)
    events = EventManager()
    event = models.ForeignKey('Event', related_name='listings', null=True, blank=True, on_delete=models.SET_NULL)

class EventManager(models.Manager):
    def get_queryset(self):
        now = arrow.now()
        # Only listings which have events ending after today
        qry = super(EventManager, self).get_queryset().filter(event__isnull=False).select_related('event').filter(to_date__gte=now.datetime)
        return qry
Run Code Online (Sandbox Code Playgroud)

ppe*_*rid 7

这似乎是一个导入时评估问题(在某种程度上是一个日期比较问题,如你所说).

一旦你的views.py模块被导入,会对该类的queryset成员EventList进行评估.结果是一个QuerySet 实例,它是在导入时计算的.因此,该.filter(to_date__gte=now.datetime)部件实际上是在当时执行的,因此日期实际上始终是相同的(导入时的日期).

在调用视图时,所有django在幕后都会将一个附加.all()到查询集,以强制对查询进行新的评估.但由于日期时间过滤器实际上是在加载模块时进行评估的,因此它将始终按相同的日期进行过滤.例如,如果您在服务器重新启动之前插入新的列表,我希望您能获得这些新结果!

对于需要动态过滤的情况,您应该覆盖该ListPageView.get_queryset方法,以强制执行运行时评估:

class EventList(ListView, FilterMixin):
   def get_queryset(self):
      return Listing.events.order_by('-from_date')
Run Code Online (Sandbox Code Playgroud)