Задать вопрос
Seletach
@Seletach
Начинающий бекендер

Как проверить что пользователь это автор в Django?

Существует вот такая CBV. Мне нужно на главной странице сделать проверку на авторство: если пользователь - автор, тогда выводим все посты этого автора и другие опубликованные, если пользователь - не автор, тогда выводим только опубликованные посты и ещё пару фильтров. Как обратиться к id модели User? От Post к User прокинут FK.
User = get_user_model()

class PostListView(ListMixin, ListView):model = Post
    ordering = '-pub_date'
    paginate_by = 10
    template_name = 'blog/index.html'
    def get_queryset(self):
        queryset = super().get_queryset().all( ).annotate(comment_count=Count("comments"))
        
        if get_object_or_404(Post,  author_id='user__id') == self.request.user:  # проверка на этой строке
            queryset = queryset.filter(author=self.request.user) 
        else:
            queryset = queryset.filter(category__is_published=True, 
                                       is_published=True,
                                       pub_date__lte=timezone.now())
        return queryset
  • Вопрос задан
  • 172 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
syschel
@syschel
freelance/python/django/backend
Проверяем авторизирован пользователь? Если да, то отдаём только те посты, где он является автором.
Если же пользователь не авторизирован, то отдаём всё остальное по вашим фильтрам
class PostListView(ListMixin, ListView):model = Post
    ordering = '-pub_date'
    paginate_by = 10
    template_name = 'blog/index.html'

    def get_queryset(self):
        queryset = super().get_queryset().all( ).annotate(comment_count=Count("comments"))
        
        if self.request.user.is_authenticated  # Проверяем пользователь авторизованный или нет
            return queryset.filter(author=self.request.user) 
        return queryset.filter(category__is_published=True, 
                                          is_published=True,
                                          pub_date__lte=timezone.now())


get_object_or_404 - Достаёт только один объект, вы же хотите получить список, судя по названию класса. При этом если вдруг не найдётся ни одной записи, то будет вызвана принудительная ошибка 404. То есть далее ваш код выполняться не будет.

Если же нужно проверить есть ли у авторизированного хоть один пост, в противном случае считаем его не "автором", то так:

def get_queryset(self):
        queryset = super().get_queryset().all( ).annotate(comment_count=Count("comments"))
        
        if self.request.user.is_authenticated  # Проверяем пользователь авторизованный или нет
            queryset =  queryset.filter(author=self.request.user) 
        if not queryset:  # либо можно так - if not len(queryset): 
            queryset = queryset.filter(category__is_published=True, 
                                              is_published=True,
                                              pub_date__lte=timezone.now())
        return queryset


Но если у вас понятие "автор" определяется не только наличием созданных им постов. То лучше вносить в модель пользователей статус автор он или нет.
class User(models.Model):
    ....
    is_author = models.BooleanField(default=False)
    ...

И тогда проверка уже будет такой

...
    def get_queryset(self):
        queryset = super().get_queryset().all( ).annotate(comment_count=Count("comments"))
        
        if self.request.user.is_authenticated and self.request.user.is_author:
            return queryset.filter(author=self.request.user) 
        return queryset.filter(category__is_published=True, 
                                          is_published=True,
                                          pub_date__lte=timezone.now())

Естественно, если пользователь автор, но постов создать не успел, то ему вернётся пустой список.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы