Категории ссылок на основе request.user.is_staff - PullRequest
0 голосов
/ 03 марта 2019

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

1 Ответ

0 голосов
/ 03 марта 2019

Это очень неэффективный способ делать вещи.Вы должны сделать фильтрацию в базе данных.Логика должна быть следующая: давать мне все категории / посты, кроме случаев, когда пользователь не является персоналом, и в этом случае фильтруйте их, чтобы они давали мне только публичные.

...