Приложение Django: UserPassesTestMixin для проверки того, что пользователь является автором сообщений, прежде чем разрешить доступ к просмотру?

#django

#django

Вопрос:

Цель моего приложения — разрешить пользователям создавать сообщения для просмотра в их собственной учетной записи.

Я использую представление на основе классов, чтобы показать текущему зарегистрированному пользователю их сообщения. Чтобы пользователи не могли видеть сообщения других пользователей, у меня есть UserPassesTestMixin test_func, который выполняет итерацию по набору запросов и проверяет, являются ли они автором этих сообщений.

Проблема, с которой я сталкиваюсь, заключается в том, что когда нет сообщений для отображения, я получаю код ошибки 404, в котором указано, что ничто не соответствует запросу. Я хочу, чтобы он по-прежнему отображал страницу, даже если доступных сообщений нет. Когда я использую только функцию get_queryset, она работает и отображает мой шаблон без сообщений, но без UserPassesTestMixin и test_func пользователь может ввести имя пользователя другого человека в URL и иметь возможность просматривать учетную запись / сообщения другого человека.

Вот код для этого представления на основе классов в моем views.py файл:

 class UserSessionListView(LoginRequiredMixin, UserPassesTestMixin, ListView):
    model = session
    template_name = 'programmerjournal/user_sessions.html'
    context_object_name = 'sessions'
    paginate_by = 24

    def get_queryset(self):
        user = get_object_or_404(User, username=self.kwargs.get('username'))
        return session.objects.filter(author=user).order_by('-date_added')

    def test_func(self):
        user = get_object_or_404(User, username=self.kwargs.get('username'))
        posts = get_list_or_404(session, author=user)
        for post in posts:
            if self.request.user == post.author:
               return True
            return False
  

Комментарии:

1. Я нахожу немного странным, что есть параметр username . Таким образом, ваш URL-адрес содержит <username> параметр, который сам по себе не является зарегистрированным пользователем?

2. Я использую встроенную пользовательскую модель Django, которая автоматически содержит атрибут username, чтобы пользователю было с чем входить.

3. обычно в Django нет username параметра URL, если вы сами его не укажете. Кроме того, промежуточное программное обеспечение аутентификации просто добавит .user атрибут к запросу, который содержит вошедшего в систему пользователя, который является объектом модели пользователя.

4. Я все еще немного новичок в Django и всех его концепциях, поэтому сначала я не был точно уверен, что вы предлагаете. После прочтения ваших дополнительных ответов и объяснений я теперь понимаю. Вы предоставили отличный ответ, который помог мне понять концепцию Django, которую я раньше не до конца понимал. Еще раз спасибо!

Ответ №1:

Когда я использую только get_queryset функцию, она работает и отображает мой шаблон без сообщений, но без UserPassesTestMixin и test_func пользователь может ввести имя пользователя другого человека в URL-адрес и иметь возможность просматривать учетную запись / сообщения другого человека.

На самом деле даже с UserPassesTestMixin в этом случае человек может войти в другую учетную запись и получить доступ, поскольку вы работаете с username и вообще никогда не принимаете во внимание вошедшего в систему пользователя.

Если вы не хотите отображать сообщения другого пользователя, вам не следует использовать <username> параметр URL. Но используйте request.user , который содержит вошедшего в систему пользователя:

 class UserSessionListView(LoginRequiredMixin, ListView):
    model = session
    template_name = 'programmerjournal/user_sessions.html'
    context_object_name = 'sessions'
    paginate_by = 24

    def get_queryset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).filter(
            author=self.request.user
        ).order_by('-date_added')  

Здесь request.user , таким образом, будет содержаться вошедший в систему пользователь. Таким образом, нет смысла сохранять имя пользователя в URL, поскольку действительно пользователи могут изменять URL.

Комментарии:

1. Я обновил представление, используя ваше предложение, и оно отлично работает! Я зайду и изменю URL-адреса, чтобы исключить имя пользователя. Большое вам спасибо!