#15. Классы представлений: ListView, DetailView, CreateView | Django уроки
Практический курс по Django: stepik.org/a/183363
Django урок 15. Что такое классы представлений (Class-Based Views - CBV), как создаются и подключаются к маршрутам (метод as_view()). Атрибуты: model, template_name, context_object_name, extra_context, allow_empty. Методы: get_context_data(), get_queryset(). Атрибуты класса DetailView: slug_url_kwarg, pk_url_kwarg. Атрибут класса CreateView: form_class и success_url. Функция reverse_lazy() и ее отличие от reverse().
Телеграм-канал: t.me/django_selfedu
Инфо-сайт: proproprogs.ru/django
lesson-15-coolsite.zip: github.com/selfedu-rus/django...
Список базовых классов: djbook.ru/rel1.9/ref/class-ba...
Русскоязычная документация по Django 3: djbook.ru/rel3.0/
Официальный сайт по Django: www.djangoproject.com
Пікірлер: 202
Картинки всё горячее с каждым уроком. Смотрю дальше)
Пытаюсь предугадать ваши действия, пишу код сам и проверяю по вам. Когда получается, радости полные штаны)
Урок просто блестящий. В одном уроке я столько своих вопросов закрыл, что нет слов. Удачи автору!
Насколько грамотная речь! И материал, и подача. Мне все очень понравилось
Чувствую, что к 26 уроку фотографии уже нужно будет цензурить😄
@tihunvolkov9288
10 ай бұрын
А ты думал для чего там галочка не публичные)
Из этого занятия стало понятно, что автор не выполнил домашнее задание по отображению главного меню через включенный тег))
я думала мы вместо allow_empty = False будем ручками прописывать условие и рейзить Http404, а оказывается и для этого свой аттрибут есть)) мне прям даже как то неудобно, что джанго за нас все делает 😀
Спасибо очень доступно, то что нравится на вашем канале!
Спасибо, Сергей! Сегодня займусь Вашим курсом по ООП. Все отлично.
Спасибо, Сергей, за твои уроки!
Сергей, вы прекрасный учитель. К сожалению, столкнулся с проблемой, что теперь хочу учить материал исключительно по вашим урокам. :) Мне кажется, что ученикам было бы очень интересно учить вместе с вами git или хотя-бы gitlab. Вы лучший. Спасибо большое за ваши труды.
На много упрощает код. Благодарю за видеоматериал!
Спасибо Вам за урок! Очень интересная тема! Теперь главное правильно выбирать класс родитель) Круто!
Спасибо Вам за такую полезную информацию, Вы спасли мой проект))
Супер! Спасибо! Это очень существенная особенность Django!
Спасибо огромное!! Так рассказывать это дар! Спасибо!
Как всегда, видеоурок на высоте!
оооо... супер👍 в основном ради class based views смотрел этот курс
Я посмотрел только 6 минуту, но уже понял что ты топовый програмист, подписка и лайк, удачи в продвижении
Большое спасибо! По документации не очень понятно, как оно всё работает, теперь документацию можно смотреть более осознанно
Автор - ты лучший!
На этом примере понял, как удобно использовать Templatetags. Так как я ранее менюшку сайта вынес в отдельный тег, то сейчас не нужно постоянно ее прописывать
Спасибо за урок
Красиво, спасибо огромное
Учитель от Бога
спасибо за такие замечательные уроки. Смотрю этот курс и параллельно документацию на русском языке, очень удобный комплект для обучения получается) потом уже если углубляться, не так страшно будет)
Круто! Отдельное спасибо за фотки барышень)
Мой маленкий совет для всех сделать кнопу "админ" в меню, чтобы в процессе содания сайта быстро переходить на страницу администратора!) просто настроить для нее url и написать функцию с содержимым "pass"
@fallennephalem1258
Жыл бұрын
а потом менять фронтенд, когда будешь её удалять
@PavelNebo
Жыл бұрын
разве написать admin в адресе долго ?
Решил вернуться к этой теме, на своём проекте реализовать DetailView. Долго мучался с FieldError. Оказалось дело в том, что у меня в модели по-другому поле со слагом называется. Итого решение - надо переопределить параметр slug_field - присвоить ему название слага в моей модели
Thank you, sir!
спасибо за видос )
мужык, ты лучший
Вот это упростили конструкцию так упростили )))) было 3 строчки кода стало 23 ))))))))
Спасибо
25:43 А если мы сделали верхнее меню через "inclusion_tag", как автор канала советовал сделать как "Домашнее Задание", то меню будет видно )
Спасибо!
Респект!!!
Спасибо.
нейминг божественный конечно
На 7:04 сказано, что можно передавать только неизменяемые данные в extra_context, но такой код сработал (использую Django 4. Возможно, в третьей версии нельзя было): class Mixin(): menu = [{'title':'статьи','url':'list'}, {'title':'новая','url':'new'}, {'title':'инфо','url':'about'}, {'title':'тема','url':'theme'}, {'title':'вход','url':'login'} ] context = { 'menu': menu, 'style': styles[0] } class List_page(Mixin, ListView): '''ОТОБРАЖЕНИЕ СПИСКА СТАТЕЙ''' model = Page context_object_name = 'list' template_name = 'pager/list.html' extra_context = Mixin.context Закинул меню таким же списком в словарь context миксина, а потом, наследовав (Mixin, ListView), передал в extra_context этот список Mixin.menu, и всё заработало в таком простом формате. p.s. спасибо за уроки, Сергей!
@selfedu_rus
10 ай бұрын
Да, я здесь не совсем верно сказал, в extra_context можно прописывать только те данные, которые известны (существуют) на момент описания класса.
Ох же, сложновато! Буду разбираться, но смогу :)
Спасибо! Надеюсь, у вас появятся видео по переводу сайта на другие языки
@vladkrolik2700
2 жыл бұрын
??? в настрой поставить другой язык и все вроде
@stevejops007
Жыл бұрын
@@vladkrolik2700 нууу почти...=)
@vladkrolik2700
Жыл бұрын
@@stevejops007 Фамилия как у меня )
Можно добавить в class show_post функцию def get_queryset(self): return Women.objects.filter(is_published=True) если без нее, то можно открыть не опубликованный пост по слагу в тестирование переиграл :)
@vanillawire1717
Жыл бұрын
Мне кажется лучше использовать get_object(self): def get_object(self): """Выбор нужной записи из таблицы 'Women'""" return get_object_or_404(Women, slug=self.kwargs['post_slug'], is_published=True) Так как я использовал ваш вариант и пытался просто filter() заменить на get() и выдавало ошибку, что оно находит не 1, а сразу 5 записей, что натолкнуло меня на мысль, что нужно туда добавить в условие проверку по slug(но оставить использовать filter()) или найти в документации Django подходящую функцию, для получения одной записи(как я показал в самом начале).
Good man)
Я пересматриваю уроки, спасибо! Хотя уже работаю программистом
Не совсем понятен механизм сохранения формы и добавление поста в базу данных. Не могу понять в какой момент, почему и откуда Джанго знает о том, что нужно добавить данные в базу данных в классе AddPage. Был бы благодарен, если бы Вы мне смогли обьяснить!)
мне кажется в 17:38 для отображения заголовка лучше использовать f строку(context['title'] = f"Category: {context['publications'][0].cat}")
На примере первых двух классов представлений и не скажешь, что есть выигрыш в количестве кода, функции выглядят компактнее.
@selfedu_rus
3 жыл бұрын
В реальности кода в функциях представлений гораздо больше, особенно, при работе с формами и здесь классы представлений очень выручают.
Привет! Спасибо за уроки! Один момент я написал extra_context и передал туда меню и у меня все сработало без функции Def get_context_data
@user-zl5sp9yh1n
Жыл бұрын
Потому что в данном случае у нас меню это статичная переменная, но если она будет меняться динамически, в зависимости от того какая страница у нас представлена то что-то пойдет не так.(допустим меню генерирует отдельная функция по объекту который передается в нее из класса или что-нибудь подобное).
Супер!) Дякую:)
Очень круто и профессионально. Мне очень нравится. Жаль только что сайт закрыт. Не понимаю, так мало времени прошло
кстати, я вот сижу и думаю, а почему у меня меню отображается? Потом вспомнил, что мы делали свой тег для категорий и для меню по желанию. Удобно
Привет! Все супер, но у меня вопрос: на 24й минуте строка 88 context['title'] = context['post'] по моему она сработала только потому, что у класса был определен метод __str__, не будет ли более правильно написать context['title'] = context['post'].title? Какое Ваше мнение?
@selfedu_rus
3 жыл бұрын
Да, совершенно верно! Вы первый, кто это отметил! Наверное, лучше все-таки явно указывать title, чтобы избежать возможных ошибок, здесь я с Вами полностью согласен.
@crazyhowling2203
3 жыл бұрын
@@selfedu_rus Думаю если ещё можно, то стоит отметить это в описании видоса
@dmitryzagorevskiy507
2 жыл бұрын
Приветствую! Отличное уточнение, только не tYtle, а title. Исправьте, пожалуйста, чтобы кто-то не повторил опечатку. Спасибо!
@Magpie2123
2 жыл бұрын
@@dmitryzagorevskiy507 Спасибо, попоавил.
Спасибо за уроки, самые лучшие в KZread ! У меня вопрос: Вы показали , как сделать автоматическое заполнение поля slug в меню-админа, а как сделать это через поле формы (где ее добавляет пользователь через CreateView... -.)?
@selfedu_rus
2 жыл бұрын
средствами JS, можно самостоятельно написать, можно найти фрагмент на просторах Интернета
Отлично !!!
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) name = Category.objects.get(slug=self.kwargs['category_slug']).name context['title'] = f'Категория - {name}' return context Так тоже работает вывод названия категории в заголовок
Спасибо за превосходное объяснение. Это лучшее, что я находил. Есть вопрос по этим классам. Во все классы мы добавляли динамический контекст. Можно объявить базовый класс с этими методами и далее наследоваться в дальнейшем? Или я забегаю вперед?
@selfedu_rus
Жыл бұрын
да, конечно, весь спектр возможностей ООП здесь можно применять
Годнота-то какая)) Лепота)
👏👍
я не англичанин конечно, но мне кажется что он упорно говорит не as, но ass view. А учитывая фотографии которые он выбирает, кажется что автор намекает нам на что-то)
Спасибо за уроки. Возник диссонанс. Почему template_name - index.html, но в urls мы указываем category html.
Чтобы уходило на 404 kzread.info/dash/bejne/kWR9psaOZrOqetI.html можно также номер категории брать не из модели Women а отдельным запросом из модели категории и из него же брать title: cat = Category.objects.get(slug=self.kwargs['cat_slug']) context['cat_selected'] = cat.pk context['title'] = 'Категория - ' + cat.name
template_ name можно и не передавать, если шаблон назвать соответственно (в данном случае women_list и women_detail) тогда джанга их автоматом найдет
Здравствуйте. Можете подсказать, в джанго kwargs имеет только параметры маршрута, или еще что-то?
Сергей, спасибо за уроки! Подскажите, почему класс WomenCategory работает без указания slug_url_kwarg, а ShowPost нет?
@selfedu_rus
Жыл бұрын
ой я уж спустя 2,5 года и не помню что за WomenCategory )) спросите в сообществе телеграм-канала, вам там подскажут.
Спасибо, суть понятна! Но кажется, что для небольших Вью вполне можно ограничится функциями.
@selfedu_rus
3 жыл бұрын
Конечно, что удобнее, то и используется!
Здравствуйте. Использую ваш курс как наглядный пример и как посредник между документацией (смотрю как делаете вы - читаю про это в документации, книге или гугле. Так, сухая документация подкрепляется реальной структурой и выстраивается полная картина проекта). Спасибо огромное. Но информации очень много и усвоить без большого количества практики - невозможно. Можете посоветовать хорошее задание? С одной стороны нагугленные по запросу проекты "для джуниор джанго дев" ещё слишком абстрактные и сложные, с другой стороны сделать простые несколько страниц сайта, с несложными моделями и логикой я уже умею. Спрашиваю на случай если у вас есть хорошее отработанное задание, а так, конечно, буду искать сам, благо технология не малоизвестная. В целом просто хотел сказать вам спасибо. Ваш канал - это находка. Обязательно послушаю про генетические алгоритмы и многое другое, после того как смогу начать реальную работу в текущей области)
@selfedu_rus
3 жыл бұрын
Спасибо! Заданий так то не делал. Как вариант попробуйте сделать более сложный сайт с набором большого числа изображений (например, формул в тексте). Подумайте как хранить такие страницы на стороне сервера, как загружать. Еще вариант сделать простой форум.
У меня почему то класс от CreateView работает только от класса формы которая непосредственно связана с моделью, с формами не связанными с моделью выдает ошибку type error 'BaseForm.__init__() got an unexpected keyword argument 'instance'' Сергей подскажите в чем проблема?
@selfedu_rus
2 жыл бұрын
Вам лучше этот вопрос в сообщество в телеграм-канале задать, там быстро ответят!
@pioner2711
2 жыл бұрын
Я так понял, что CreateView нужен именно для работы с формами связанными с моделями, а для форм не связанными с моделями нужно наследоваться от FormView???
Спасибо, прекрасный урок. Но возник один вопрос. 24:29 , 51 строка, почему нельзя использовать редирект на ‘home’?
@crazyhowling2203
3 жыл бұрын
Так можно или нельзя? Самому интересно
Спасибо большое за урок! У меня возник вопрос: зачем в определении функции def get_context_data(self, *, object_list=None, **kwargs): мы передаем "*" и "object_list=None", если оно все равно не используеться?
@stmustbk
Жыл бұрын
Мне кажется что оно используется, просто когда его все же нет, мы передаём его как None. Чтобы Джанго не выдавал ошибку
@nevermore222
Жыл бұрын
@@stmustbkя его из кода убрал . Ничего вроде не поменялось
@stmustbk
Жыл бұрын
@@nevermore222 в старых версиях приходилось его писать
@nevermore222
Жыл бұрын
@@stmustbk а ну то есть сейчас достаточно писать self в аргументах и более ничего не указывать и он будет работать? Теперь вроде бы ясно стало спасибо
Большое спасибо за супер уроки! Пожалуйста ответьте на один вопрос: Если в адресном поле пишем адрес тогда всё понятно, вызывается функция path и ищет соответствие адреса к маршруту и если есть соответствие тогда вызывается представление и потом уже шаблон. А вот когда нажимаем кнопку "читать пост" тогда кто кого вызывает? Откуда начинается цепь вызовов? В этом случае в адресном поле мы же ничего не пишем!
@selfedu_rus
2 жыл бұрын
Когда нажимаете на кнопку, то это такой же переход по URL-адресу, который в ней прописан. Если это обычная ссылка, то имеем GET-запрос к серверу, если форма, то может быть и дургой тип запроса.
@bastibubu5154
2 жыл бұрын
@@selfedu_rus Понял. Спасибо!
Сергей, не обязательства ради, а понимания для, не могли бы Вы примерно сориентировать какие у Вас предположительные прогнозы по времени начала и окончания вашего очередного шедеврального курса по Django REST framework? Заранее большое спасибо хотя бы за очень приблизительный прогноз по времени.
@selfedu_rus
2 жыл бұрын
думаю, в конце января начнем )
Всё прекрасно, но есть вопрос, почему бы WomenCategory не наследовать от WomenHome и просто переопределить нужные методы? Просто ключевое отличие в фильтре. ИЛИ сделать всё ещё хитрее и определить некий WomenView где мы допустим будем указывать все стандартные методы(допустим настройки header) и от него уже дальше наследоваться.
context["posts"][0].cat работает только в том случае, если есть хотя-бы одна запись, У меня идет еще категория "Другое" без записей, и она так не отображается, падает ошибка
Когда лучше использовать классы представления, а когда функции?
При cat тоже работает context['cat_selected'] = context['posts'][0].cat - вместо cat_id - я помню Сергей говорил, что это почти одно и то же - я проверил в shell и там cat возвращает то что мы определили в __str__ в модели, а cat_id - pk (id, fk - кому как угодно) Category - я так понимаю мы ставили там cat_id для шаблона list_categories - но при изменении про которое я написал - всё работает - кто-то может объяснить почему?
Спасибо за урок! Но почему бы в get_queryset не возвращать вместо "Women.objects.filter(...)" "self.model.objects.filter(...)"?
@selfedu_rus
2 жыл бұрын
Упс... я уже сейчас такую тонкость не помню )
У меня почему то не отображаются поля в классах CreateView и FormView. Может из-за того что они унаследованы от ModelForm в файле forms.py?
здравствуйте, извините, при проектирование подобного сайта возник вопрос, а что делать, если, условно, я хочу вывести в блок контента не только статьи, но и сами категории, вот так к примеру, певица: Пугачева, Лолита; актрисы: ходченкова; и возникает ВОПРОС, а как корректно передать класс представления несколько моделей ? Не уверен, что смогу получить ответ, но все же мало ли, заранее спасибо за ответ, многоуважаемый автор!!!
Подскажите пожалуйста, если я еще на прошлом уроке наш список menu "обернул" в inclusion_tag и передал функцию в base.html будет ли это "ошибкой" или недочетом, хотя теперь наше меню у нас есть всегда)
@selfedu_rus
Жыл бұрын
можно, ошибки не будет
@zeinmusic3649
Жыл бұрын
@@selfedu_rus благодарю вас!)
Спасибо вам за уроки. Очень внятно и подробно. Почему то при открывании поста через класс. Не хочет работать slug по какой-то причине конфликтует с pk. С функцией все работает. Пользовательский слаг везде переименовал. На всякий случай удалил старые миграции, и заново сделал. Но все равно ругается на эти атрибуты(
@AlexeyTeacher
2 жыл бұрын
Если сделать по pk, то начинает работать. Но странно, я же делаю слаг(
@AlexeyTeacher
2 жыл бұрын
Это только detailview только проблема(
@selfedu_rus
2 жыл бұрын
да, по умолчанию идентификатор в Django следует брать по атрибуту pk
@AlexeyTeacher
2 жыл бұрын
@@selfedu_rus Но как переделать на слаг?)
@selfedu_rus
2 жыл бұрын
@@AlexeyTeacher Я, вроде, там дальше показываю, как по слагу выбирать запись (если не в этом, то в другом уроке).
На 11:15 Думаю лучше писать не return Women.objects.filter(is_published=True) А; return self.model.objects.filter(is_published=True) чтобы не нарушать принцип так какой-то про хранение всего в одном месте
@urrchach
10 ай бұрын
Мне не помогло😢
У меня эта шапка сайта с навигацией сразу работала на главной странице, это из за того что я сделал домашнее задание?
@163AlejanD
2 жыл бұрын
да
кто дз выполнил с меню, сейчас добавлять нечего не нужно)
Объясните пожалуйста, в каких случаях лучше использовать какой класс View
@selfedu_rus
2 жыл бұрын
В зависимости от вида выдаваемой информации на странице (список, статья, форма и т.п.).
А как правильно указать в DetailView, если у меня так "/ slug_url_kwarg = 'post_cat' slug_url_kwarg = 'post_slug' Списком он не принимает. Просто у меня получилось, если с такими двумя, да и с одним получается. Но хотелось бы ещё, чтоб если я менял название категории на другое, то выдавало бы ошибку 404, а не ту же новость.
Ох, как всё сложно. Спасибо за урок, как всегда очень подробно. А зачем вообще делать эти все представления, а не просто по конкретным URL выдавать нужные html страницы и в них выводить как и раньше? Так выглядит намного сложнее всё. В данный момент я разбираюсь с wagtail, там чуть проще, но нужно и простой джанго знать так же.
@johndoe9604
Жыл бұрын
Выглядит сложнее по началу, но в последующем, если ты будешь писать большое веб-приложение, будет много головной боли если делать все «по простому»
вопрос, почему на каждый шаблон мы передаем menu неужели нельзя сделать в базовом шаблоне и больше к нему не возвращаться?
И django сам проверит если форма валидна? is_valid() спс за уроки, у вас самые топовые
@selfedu_rus
3 жыл бұрын
да, в соответствии с настроенными валидаторами в модели формы
Спасибо! шаг за шагом появляется ясность. У меня вопрос. Если модель1 имеет форин кей к другой модели2, и мне нужно сделать форму по добавлению записи в модель1. Как мне это сделать? джанго ругается, что поле не ссылается на внешнюю модель2 (мне понятно, что там такой записи нет). Как сделать, чтобы объединить такое добавление? просто сделать модель2.objects.create(поле='значение') и потом form.save()?? или есть проще метод?
@selfedu_rus
Жыл бұрын
Лучше это обсудить в ТГ-канале (ссылка под видео). А в двух словах, Django, скорее ругается, что поле не заполнено (а не то, что оно не связано, связь, как раз в модели указана). Тут возможно параметр default нужно еще прописать, тогда при добавлении новой записи в модель2 пойдет значение по умолчанию, но тогда оно будет дублироваться, а это, скорее всего, недопустимо. В общем, надо подумать, чтобы не было дублирования и значение автоматом прописывалось. Варианты есть.
В ShowPost забыли добавить context['cat_selected'] = context['post'].cat_id, чтобы при просмотре поста выделялась категория, к которой принадлежит девушка (по мне это не очень решение, т.к. я не могу теперь перейти быстро на всех девушек из этой категории, но так было в функции отображения, но пропало в классе) :)
@selfedu_rus
3 жыл бұрын
Уже не помню такие что было в 15-м занятии, возможно, просто демонстрировал празличные классы представлений. На следующем все это сделано через миксины.
Вы говорите что в словаре extra_context можно передавать только статические данные, это не так. У меня любые данные работают: списки, выборки из моделей, можно хоть форму передать. Меню отлично передается и работает. Я что то упускаю?
хмб.. у меня меню уже в пользтегах, вот если оно так, то могу же я просто выдернуть словари из тегов?? только не получается чего-то
Доброго времени. У меня такой вопрос возник. Если у меня поле в моделе называется не slug, а url. В таком случае использование атрибута slug_url_kwarg(класса DetailView) выдает ошибку FieldError. Как быть? Поле переименовывать не хочется
@user-vb9jj2pq4u
3 жыл бұрын
Сам разобрался. Необходимо тогда прописать атрибут slug_field с нужным значением(в моем случае 'url'), а уже после него slug_url_kwarg с таким же значением
На 23:21 Как класс представления ShowPost понял, что нужно брать одну запись и именно с Шакирой (на которую нажали)? В функции представлении мы делали фильтрацию по слагу. А здесь как?
@V.D.
10 ай бұрын
Автору вопроса, надеюсь, уже давно всё понятно, а тем, кому не понятно - по полю РК или слаг. ?В этом случае по слагу "тайтл" = имя героини? Через урлконф
Как нужно прописать форму в шаблоне? Так же как и раньше?
Добрый день! Помогите советом. Цель: создать список фотоальбомов(категории), добавлять в них фото, в зависимости от альбома. Вопрос: как правильно прописать функцию get_queryset для вывода фото по выбранному альбому? # Модель альбома с фотографиями class Album(models.Model): title = models.CharField(max_length=100, verbose_name='Название Альбома') slug = models.SlugField(unique=True, db_index=True, verbose_name='URL Альбома') image = models.ImageField(upload_to='photo/%Y/%m/%d', verbose_name='Обложка') def __str__(self): return self.title def get_absolute_url(self): return reverse('gallery', kwargs={'album_slug': self.slug}) class Meta: verbose_name = 'Album' verbose_name_plural = 'Albums' ordering = ['title'] # Модель фото для альбома class Photo(models.Model): photo = models.ImageField(upload_to='photo/%Y/%m/%d', verbose_name='Фото') album = models.ForeignKey(Album, on_delete=models.PROTECT, null=True, verbose_name='Альбом') class Meta: verbose_name = 'Photo' verbose_name_plural = 'Photos'
Добрый вечер! Как правильнее то в итоге делать: на функциях или на объектах???
@selfedu_rus
2 жыл бұрын
зависит от задачи, как удобнее
Вот я что то не понимаю . А зачем в аргументах get_context_data - '*' и 'object_list=None' ? Я их вроде удалил и ничего не поменялось . Да и нигде не используется оно вроде бы
Меняя параметр context_object_name = "posts" откуда собственно говоря берётся данная переменная posts этот момент мне крайне не понятен, условнов object_name я могу понять он создаётся при создании model = Women, но откуда появляется переменная с этими данными posts, или это обычный ренейм object_name???
@selfedu_rus
3 жыл бұрын
Здесь мы присваиваем строку 'posts', на основе которой уже в шаблоне автоматически создается переменная с этим именем. Происходит неявно, но нам это и не важно.