我需要一些指导或帮助,如何解决此问题。
因此,我想基于request.user.is_staff
生成类别链接
目前,我可以执行此操作,但是它会进行一些重复的查询。
当前方法是下一个, 我有一个上下文处理器,它会生成类别链接
def blog_category_links(request):
context = dict()
queryset = Post.objects.select_related('category').distinct()
context['categories'] = set([post.category for post in queryset if post.is_public or request.user.is_staff])
return context
当我访问博客索引页面时,除一种情况外,所有情况都可以正常工作。
方法几乎相同。
queryset = Post.objects.select_related('category').select_related('author').prefetch_related('tags').distinct()
...
posts = [post for post in queryset if post.is_public or request.user.is_staff]
return posts
使用这种解决方案,如果我没有登录,我会得到5个查询,大约10毫秒的时间,没有重复。如果我登录,我会得到7个查询〜12ms时间,其中有2个重复(用户查询)
所以我知道这不是最好的设计。这就是为什么我想寻求帮助的原因。
谢谢
更新:
这是我的类别模型
class Category(models.Model):
""" Category model."""
name = models.CharField(_('category name'), max_length=50)
slug = models.SlugField(_('category slug'), max_length=50, blank=True)
这是我的Post模型:
class Post(ContentModel):
"""Post model."""
STATUSES = Choices(
(0, 'draft', _('draft')),
(1, 'published', _('published')),
(2, 'private', _('private')),
)
author = models.ForeignKey(User, on_delete=models.CASCADE, limit_choices_to={'is_staff': True},
null=True, related_name='blog_posts')
category = models.ForeignKey('Category', on_delete=models.CASCADE)
tags = models.ManyToManyField('Tag')
title = models.CharField(_('post title'), max_length=100)
slug = models.SlugField(_('post slug'), max_length=105, blank=True, unique=True)
head_image = models.ImageField(upload_to='uploads/', default='no-image')
status = models.IntegerField(choices=STATUSES, default=STATUSES.draft, db_index=True)
pub_date = models.DateTimeField(_('publication date'), default=timezone.now)
comments = models.BooleanField(_('allow comments'), default=True)
view_count = models.IntegerField(_('sum of views'), default=0)
favs = models.IntegerField(_('sum of favourites'), default=0)
class Meta:
unique_together = ('slug', 'created')
ordering = ['-pub_date']
objects = models.Manager()
@property
def is_public(self):
if self.status is Post.STATUSES.published and not self.pub_date > timezone.now():
return True
else:
return False
答案 0 :(得分:0)
这是一种非常低效的处理方式。您应该在数据库中进行过滤。逻辑应该是:给我所有类别/职位,除非用户不是职员,在这种情况下,将其过滤以仅给我公开类别/职位。
categories = Category.objects.all()
if not request.user.is_staff:
categories = categories.filter(post__status=1, post__pub_date__gte=timezone.now())
...
posts = Post.objects.select_related('category').select_related('author').prefetch_related('tags')
if not request.user.is_staff:
posts = posts.filter(status=1, pub_date__gte=timezone.now())