#python #django #django-class-based-views
#python #django #представления на основе классов django
Вопрос:
в разделе контактов панели инструментов моих проектов сохраненные контакты видны только автору, но ранее они были видны всем, потому что я забыл включить UserPassesTestMixin
в CBV. Я включил, но браузер показал мне ошибку с именем NotImplemented test_func, я также реализовал test_func
views.py
class ContactListView(LoginRequiredMixin, UserPassesTestMixin, ListView):
model = ClientContact
template_name = 'site/contacts.html'
context_object_name = 'contacts'
ordering = ['created_at', '-updated_at']
def test_func(self):
contact = self.get_object()
if self.request.user == contact.author:
return True
return False
в нем снова говорится, что не выполненный test_func, а также get_oject являются неразрешенной ссылкой в ListView
Я уверен, что делаю что-то не так, но я не могу найти свою ошибку. Пожалуйста, если кто-нибудь, кто это знает, поправьте меня! Спасибо
Комментарии:
1. Когда вы задаете вопросы об ошибках, пожалуйста, покажите полную обратную трассировку — это значительно проясняет, откуда исходит ошибка.
Ответ №1:
ListView
предназначен для отображения нескольких объектов, поэтому вызывать его не имеет смысла get_object()
(что для представлений для одного объекта, например DetailView
).
Обычный подход к просмотру списков заключается в переопределении get_queryset
и фильтрации набора запросов, чтобы показывать только объекты этого пользователя.
class ContactListView(LoginRequiredMixin, ListView):
model = ClientContact
template_name = 'site/contacts.html'
context_object_name = 'contacts'
ordering = ['created_at', '-updated_at']
def get_queryset(self):
return super(ContactListView, self).get_queryset().filter(author=self.request.user)
У вас уже есть LoginRequiredMixin
, который будет обрабатывать случай, когда пользователь не вошел в систему.
Если вы хотите отфильтровать набор запросов в нескольких списковых представлениях, вы могли бы написать mixin, например:
class AuthorMixin(object):
def get_queryset(self):
return super(AuthorMixin, self).get_queryset().filter(author=self.request.user)
Затем используйте его в своем представлении как:
class ContactListView(LoginRequiredMixin, AuthorMixin, ListView):
...
Обратите внимание, что приведенное выше не проверено, оно требует LoginRequiredMixin
(поскольку оно не обрабатывает случай анонимного пользователя), и оно будет работать только в том случае, если указан внешний ключ пользователя author
. Вы могли бы улучшить смешивание, но вы можете предпочесть повторить get_queryset
метод.
Комментарии:
1. спасибо @Alasdair, наконец-то это работает. Я собираюсь задать пару вопросов, потому что я новичок в django, для каждого объекта я должен написать этот набор запросов или я могу вставить его в файл и вызвать его? и в моем проекте есть еще один шаг после регистрации пользователя под названием «нажмите, чтобы закончить», где пользователи могут заполнить свой профиль. Когда пользователь создается, он перенаправляется на dashborad, он должен автоматически переопределить страницу завершения профиля, которую я отложил, чтобы сделать это, потому что это заняло много времени. Вот почему можете дать мне представление об этом, пожалуйста, если вы не возражаете?
2. Если вы хотите повторно использовать код в представлениях на основе классов, правильный подход — использовать mixin. Я добавил простой пример выше. Ваш вопрос о создании пользователя звучит как отдельная проблема, поэтому я не могу с этим помочь.