查询集中缺少对象

时间:2014-06-04 14:42:13

标签: python django django-queryset

我有一个模特:

class Post(models.Model):
    is_active = models.BooleanField()
    created = models.DateTimeField()

两个CBV:PostListView和PostDetailView。

queryset = Post.objects.filter(is_active=True, created__lt=timezone.now())

在这两种情况下。

问题:每个第二个PostListView呈现响应没有一个带created=datetime.datetime(2014, 5, 29, 13, 40, tzinfo=<UTC>)的Post实例。 PostDetailView返回404(每2个响应!)。它很好,当我试图重现shell中的bug时:

>>> Post.objects.filter(is_active=True, created__lte=timezone.now())
[<Post: 1>, <Post: 2>]
>>> Post.objects.filter(is_active=True, created__lte=timezone.now())
[<Post: 1>, <Post: 2>]
>>> Post.objects.filter(is_active=True, created__lte=timezone.now())
[<Post: 1>, <Post: 2>]
>>> Post.objects.filter(is_active=True, created__lte=timezone.now())
[<Post: 1>, <Post: 2>]

更新

class PostListView(ListView):
    queryset = Post.objects.filter(is_active=True, created__lt=timezone.now())
    context_object_name = 'posts'

    def get_context_data(self, **kwargs):
        context = super(PostListView, self).get_context_data(**kwargs)
        context['recommended'] = self.get_queryset().filter(is_recommended=True)[:5]
        return context


class PostDetailView(DetailView):
    queryset = Post.objects.filter(is_active=True, created__lt=timezone.now())
    context_object_name = 'post'

    def get_context_data(self, **kwargs):
        context = super(PostDetailView, self).get_context_data(**kwargs)
        context['recommended'] = self.get_queryset().filter(is_recommended=True)[:5]
        return context


print self.get_queryset().query
SELECT `blog_post`.`id`, `blog_post`.`title`, `blog_post`.`slug`, `blog_post`.`meta_description`, `blog_post`.`img`, `blog_post`.`announcement`, `blog_post`.`content`, `blog_post`.`author_id`, `blog_post`.`is_innovation`, `blog_post`.`is_recommended`, `blog_post`.`is_active`, `blog_post`.`created` FROM `blog_post` WHERE (`blog_post`.`created` < 2014-06-04 15:02:44  AND `blog_post`.`is_active` = True ) ORDER BY `blog_post`.`created` DESC
  
    
      

print Post.objects.filter(is_active = True,created__lt = timezone.now())。query       选择blog_postidblog_posttitleblog_postslugblog_postmeta_description,{ {1}}。blog_postimgblog_postannouncementblog_postcontentblog_post,{{1 }。{。{1}},author_idblog_postis_innovationblog_postis_recommendedblog_post FROM is_active WHERE(blog_postcreated&lt; 2014-06-04 15:11:42 AND blog_postblog_post = True)ORDER BY created。{{ 1}} DESC

    
  

在nginx + gunicorn + gevent(Ubuntu服务器,MySQL)上运行。

1 个答案:

答案 0 :(得分:3)

如果您要对查询集过滤器使用函数调用,则无法将其设置为属性。您必须覆盖get_queryset

def get_queryset(self):
    queryset = super(PostListView, self).get_queryset()
    return queryset.filter(is_active=True, created__lt=timezone.now())

原因是因为timezone.now()将始终返回首次编译类时的值。您可以使用.filter(created__lt=timezone.now)离开,但我还没有尝试过。