Комментарии 19
Продолжайте дальше :)
Хотелось бы увидеть что-нибудь с реализациями CreateView, и что-нибудь интересное с BaseDateListView.
Хотелось бы увидеть что-нибудь с реализациями CreateView, и что-нибудь интересное с BaseDateListView.
Мне кажется, что за формирование кверисета
По-моему, рабочая вьюха с минимальной функциональностью делается так:
Обратите внимание, никаких перекрытий
Собственно, весь Ваш код можно переписать компактнее
Я не проверял, но мне кажется, что должно быть примерно так :)
А вообще, конечно, погорячились разработчики Джанги с обязательным введением CBV. Начнут ведь теперь лепить классы везде где надо и не надо
get_queryset()
должен отвечать. А он тут статичен, зато вся логика по его созданию и изменению в зависимости от условий размазывается в dispatch()
, который суть точка входа и желательно его по возможности вообще не трогать.По-моему, рабочая вьюха с минимальной функциональностью делается так:
class PostView(ListView):
model = Post
Обратите внимание, никаких перекрытий
dispatch()
и прочего. Пагинацию тоже не надо использовать низкоуровнево: в ListView, примесью которого является MultipleObjectMixin, она (пагинация) работает по умолчанию (пруф и примеры)Собственно, весь Ваш код можно переписать компактнее
class PostView(ListView):
"""
Просмотр списка статей, доступных текущему пользователю
"""
model = Post
context_object_name = 'posts'
template_name = 'posts.html'
def queryset(self):
qs = Post.objects.filter(is_delete=False).order_by('-created_at')
if not request.user.is_authenticated():
qs = qs.exclude(is_private=True)
return qs
class PostsIndex(PaginatedList):
"""
Список статей для главной страницы
"""
def get_queryset(self):
return super(PostsIndex, self).get_queryset().exclude(rating__lt=10)
Я не проверял, но мне кажется, что должно быть примерно так :)
А вообще, конечно, погорячились разработчики Джанги с обязательным введением CBV. Начнут ведь теперь лепить классы везде где надо и не надо
упс, сразу же работа над ошибками:
- в
PostView
следует читатьqueryset
, аget_queryset
- в нём же: не
request
, аself.request
Ну вообще вы правы. Можно вообще все данные отображения свести до одного класса и реализовать классический RESTful. И насчет использования CBV это тоже холивар не для хабра) Просто в данной статье хотелось подчеркнуть особенности использования, показания лучшие стороны в ООП подобных отображений. То есть, что можно отнаследоваться от базового ListView и сделать свой класс с пагинацией, затем уже отнаследоваться от него и возвращать уже пагинованные списки объектов. Если делать все «по-человечески», то это можно реализовать в том числе «примесями (mixens)». ООП предлагает множество путей решения проблемы.
И да, везде использовать это не стоит, но иногда оправдано. Например, недавно решил переписать проект полностью на CBV, в итоге на логику отображений ушло намного меньше кода.
И да, везде использовать это не стоит, но иногда оправдано. Например, недавно решил переписать проект полностью на CBV, в итоге на логику отображений ушло намного меньше кода.
Можно вообще все данные отображения свести до одного класса и реализовать классический RESTful.
Мне кажется, вместо «можно» нужно употрелять слово «нужно». Собственно, они для того и писались.
Просто в данной статье хотелось подчеркнуть особенности использования, показания лучшие стороны в ООП подобных отображений
Самое грустное в том, что это неправильный пример. Я бы даже сказал — антипаттерн. Потому что (возможно, повторюсь):
- много
буквстрок, следовательно «одним взглядом» весь код не охватить и не понять. - написание собственного велосипеда вместо использования готового решения — это я в сторону пагинации. Вы на коленке реализовали то, что уже работает (и лучше :-)) из коробки.
- логика разбора кверисета находится совсем не там, где ей надлежит быть
- и таки да — перекрытие dispatch. Этого лучше по возможности избегать. Понятно, конечно, что далеко не всегда это пожелание осуществимо, но в данном случае — да.
Практическая полезность этого кода в том, что вы открыли dispatch — точку входа во вьюху. Молодым исследователям будет понятно, с чего начинать. Но я бы сделал приписку: «в чистом виде такой код к применению не рекомендуется» :-)
Насчет dispatch и get_queryset, в принципе, полностью согласен. Но пример не совсем удачный скорее не потому, что его можно сделать меньше, а потому, что он охватывает всего пару методов, имеющихся в CBV. В идеале, для лучшего восприятия материала, надо было показать работу и с остальными методами. Вот только не знаю как это лучше реализовать, чтобы все и сразу. А делать для этого отдельную статью было бы излишне с моей стороны.
Спасибо вам за конструктивные комментарии. Как я уже написал в статье — информации по CBV и правильным практикам их применения очень мало. Большинство их сходится лишь к холиварам на темы плохо это или хорошо. Поэтому все приходится изучать путем проб, ошибок и просмотра исходного кода. Пример в статье перепишу с учетом вашего комментария.
Спасибо вам за конструктивные комментарии. Как я уже написал в статье — информации по CBV и правильным практикам их применения очень мало. Большинство их сходится лишь к холиварам на темы плохо это или хорошо. Поэтому все приходится изучать путем проб, ошибок и просмотра исходного кода. Пример в статье перепишу с учетом вашего комментария.
А в чем преимущество использования ООП во View?
Думаю то же, что и использование в других местах. Это не совсем преимущество, просто другой угол зрения, но для меня более удобным является возможность сделать базовый класс, определить функциональность, которая требуется в других отображениях. Затем данный класс можно наследовать другими отображениями как «примеси», используя на порядок меньше кода. Множественное наследование позволяет использовать несколько «примесей» для одного отображения, главное не забыть проконтролировать их порядок применения и конфликты.
*(а я кланяюсь, кланяюсь)*
Не надо наследоваться от MultipleObjectMixin: ListView уже сделал это за Вас.
class Posts(ListView, MultipleObjectMixin):
Не надо наследоваться от MultipleObjectMixin: ListView уже сделал это за Вас.
И снова от меня тысяча благодарностей :) Действительно, я даже не удосужился посмотреть в исходный код. Радует, что разработчики django предусмотрели в списке объектов пагинацию «из коробки». Однако огорчает обилие лишних переменных. Все эти object_list и page_obj стоило, наверное, как-то собрать в 1 объект, чтобы было проще вызывать в шаблоне.
После обновления примера объяснение к нему больше не соответствует коду, надо бы тоже поправить. Ну и
теперь можно убрать.
import MultipleObjectMixin
теперь можно убрать.
Да уж скорее бы :) Чувствовал себя идиотом, пока не дошло что код не тот. Ну или по крайней мере UPD подвиньте повыше, читатель пока до него не дойдет будет сидеть с круглыми глазами.
Вроде исправил) Прошу прощения, что сразу не заметил новые комментарии, по какой-то причине слетела подписка на статью, обнаружил чисто случайно.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Немного подробностей про Class Based View, ч.1