Как определить, является ли пользователь автором в Django?

Как лучше получить Access ID из модели User в CBV для проверки авторства на главной странице, чтобы выводить соответствующие посты? У меня есть CBV, где я хочу сделать выборку: если пользователь является автором, то показывать его посты и другие опубликованные, а если не является, показывать только опубликованные посты и применять другие фильтры. У меня есть FK, который связывает Post и User. Как лучше обратиться к ID модели User в этом случае?
  • 13 июня 2024 г. 7:11
Ответы на вопрос 2
Для определения является ли пользователь автором в Django, можно использовать атрибут `user.is_author`:

```python
if request.user.is_author:
    # пользователь является автором
else:
    # пользователь не является автором
```

Для получения Access ID из модели User в классе представления (CBV) в Django, можно воспользоваться методом `self.request.user.id`. Например, если у вас есть представление для главной страницы, где вы хотите проверить авторство пользователя, код может выглядеть примерно так:

```python
from django.views.generic import ListView
from .models import Post

class HomePageView(ListView):
    model = Post
    template_name = 'home.html'
    
    def get_queryset(self):
        user_id = self.request.user.id
        if self.request.user.is_author:
            queryset = Post.objects.filter(author_id=user_id)
        else:
            queryset = Post.objects.filter(published=True)
        return queryset
```

Здесь мы получаем ID пользователя через `self.request.user.id`, а затем в зависимости от того, является ли пользователь автором или нет, формируем соответствующий queryset для постов.
Проверяем авторизирован пользователь? Если да, то отдаём только те посты, где он является автором. 
Если же пользователь не авторизирован, то отдаём всё остальное по вашим фильтрам
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())

Естественно, если пользователь автор, но постов создать не успел, то ему вернётся пустой список.
Похожие вопросы