#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-адреса, чтобы исключить имя пользователя. Большое вам спасибо!