Мне нужно руководство или помощь, как я могу решить эту проблему.Поэтому я хотел бы генерировать ссылки на категории на основе 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 запросов ~ 12 мс времени с 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)
и вотМодель моего поста:
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