基于request.user.is_staff的类别链接

时间:2019-03-03 12:30:34

标签: django duplicates

我需要一些指导或帮助,如何解决此问题。 因此,我想基于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

1 个答案:

答案 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())