Как мы знаем - QuerySet(QS) - ленивы. Т.е. они выполняются только тогда, когда это надо. С одной стороны это хорошо - плюсы очевидны.
Однако, есть обратная сторона медали. Предположим, что у нас есть блог. У блога есть читатели и читатели хотят видеть новые(не читанные посты) - помеченными.
окей, создаем такую модель:
class Post(models.Model):
slug = models.SlugField()
title = models.CharField(max_length=255)
body = tinymce_models.HTMLField() #ну или models.TextField()
date = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(User, related_name='support_posts')
viewed = models.ManyToManyField(User, blank=True)
groups = models.ManyToManyField(Group)
class Meta:
verbose_name = 'Post'
verbose_name_plural = 'Posts'
def __unicode__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
Вроде все нормально и логично. У нас есть поле viewed которое отвечает за то, что хранит списки прочитавших пост. Все норм.
Но вот проблема, мы хотим пометить все новые посты прочтенными, после первого открытия страницы(тут именно так, ибо так отображаются посты - в бутстраповском аккордоне). Т.е. мы выбираем посты(ленивым QS) и потом ставим всем выбранным viewed:
@login_required
def posts_list(request, page = None):
if request.is_ajax():
posts = Post.objects.filter(groups__in = request.user.groups.all(),)
p = Paginator(posts, 10)
try:
post_list = p.page(page)
except PageNotAnInteger:
post_list = p.page(1)
except EmptyPage:
post_list = p.page(p.num_pages)
for post in post_list:
post.viewed.add(request.user)
return render_to_response('support/posts.html', {'posts':post_list}, context_instance=RequestContext(request))
return HttpResponseForbidden('[{"error":"Wrong headers."}]', mimetype='application/json; charset=utf8')
А шаблон... а шаблон такой:
{%if not request.user in post.viewed.all%}
<span class="badge badge-important">New</span>
{%endif%}
И так мы имеем собранные QS по нужному правилу, но до передачи его в шаблон он изменяется и кэшированной версии не остается, так как QS ленив.
Вопрос, как с этим бороться?:) Как инициализировать QS и поможет ли это?