Уроки Django 3 - фильтр фильмов, Q в django - урок 17
Создаем фильтр для фильмов по жанрам и годам. Рассмотрим об объект Q django. Передача информации в шаблон не используя get_context_data. Уроки Django 3
Не забудь подписаться на канал, чтобы не пропустить новые видео.
Проект на GitHub - clck.ru/M8kxs
--=--
Подписывайся на Telegram канал - t.me/django_school
О веб разработке и программировании простым языком.
То что поможет стать высококвалифицированным специалистом.
Спонсорство - boosty.to/djangoschool
--=--
🔥Провожу индивидуальные занятия по python и веб разработке (django, fastapi, flask, javascript).
Обучаю с нуля, а так же провожу консультации для мидлов и синьоров./ djangochannel
--=--
#django #программирование #python
Пікірлер: 106
Подписывайся на Telegram канал - t.me/django_school О веб разработке и программировании простым языком. То что поможет стать высококвалифицированным специалистом.
Хороший урок, курс целиком не смотрел, но во время работы над пет-проектом возникли некоторые трудности в совмещении ajax-фильтра и пагинации, часть видео из этого цикла реально помогли. Думаю, что и остальные видео этого курса отличные!
Ребят, у меня было три чекбокса и я хотел иметь возможность фильтрации по одному, двум или сразу трём полям. Это реально сделать без повторений разных комбинаций. Мне помогли, а я вам:) Это способ "дополнения" условий к фильтру def get_queryset(self): my_q = Q() if 'nations' in self.request.GET: my_q = Q(vehicle__nation__in=self.request.GET.getlist('nations')) if 'levels' in self.request.GET: my_q &= Q(vehicle__level__in=self.request.GET.getlist('levels')) if 'types' in self.request.GET: my_q &= Q(vehicle__vehicle_type__in=self.request.GET.getlist('types')) queryset = VehicleReviews.objects.filter(my_q) return queryset
@conradgrays4545
Жыл бұрын
От всей души спасибо.
Спасибо большое! Супер уроки по Django!
Спасибо огромное за просто суперский урок
Как всегда вышка !!! и с Вадимом Шаройкин оном тоже согласен.
Спасибо за урок!
Да, прикрути пожалуйста ajax , чтобы без обновления фильтровались, думаю многие будут благодарны А так урок как всегда на высшем уровне Лайк за твою работу
@DjangoSchool
4 жыл бұрын
Уговорили, сделаю
@vitaliiananiev5038
2 жыл бұрын
@@DjangoSchool а где можно посмотреть реализацию с ajax?
@DjangoSchool
2 жыл бұрын
@@vitaliiananiev5038 kzread.info/dash/bejne/g3qtwbSmoK2airQ.html
Для тех кто пишет, что хочет при выборе всех боевиков только определенного года выводились не все боевики,а только выбранного года: def get_queryset(self): if 'genre' in self.request.GET and 'year' in self.request.GET: print('if genre and year') queryset = Movie.objects.filter( Q(year__in=self.request.GET.getlist("year")) , Q(genres__in=self.request.GET.getlist("genre")) ) else: print('else') queryset = Movie.objects.filter( Q(year__in=self.request.GET.getlist("year")) | Q(genres__in=self.request.GET.getlist("genre")) ) return queryset
@user-xw4uk6cn4j
2 жыл бұрын
Спасибо
@user-vw3tx4hq6g
2 жыл бұрын
спасибо!
@linarusmanow7838
Жыл бұрын
а если таких параметров будет 5, тоже через if писать или можно как-то компактнее придумать ?
@slaviknaz7154
Жыл бұрын
@@linarusmanow7838 Решил как-то ?
@user-xh2wb3rv3e
Жыл бұрын
@@slaviknaz7154 def get_queryset(self): my_q = Q() if 'nations' in self.request.GET: my_q = Q(vehicle__nation__in=self.request.GET.getlist('nations')) if 'levels' in self.request.GET: my_q &= Q(vehicle__level__in=self.request.GET.getlist('levels')) if 'types' in self.request.GET: my_q &= Q(vehicle__vehicle_type__in=self.request.GET.getlist('types')) queryset = VehicleReviews.objects.filter(my_q) return queryset
Большое благодарю, спас мой заказ одной непримечательной вещью :)
@DjangoSchool
4 жыл бұрын
Привет, какой вещью?
@kalik54
4 жыл бұрын
@@DjangoSchool request.GET.getlist() мне надо было брать все значения атрибута, но не знал как такое сделать
@DjangoSchool
4 жыл бұрын
@@kalik54 рад что помог
Ребят, всем привет!:) Я делаю немножко другой проект, основываясь на уроках Михаила. Было две проблемы. 1) ругался на отсутствие шаблона TemplateDoesNotExist at /filter_reviews/ - Чтобы исправить - прописал в модели Фильтров template_name = 'vehicle_reviews/review_list.html'. 2) Не отображались результаты поиска, была пустая страница. Для решения так-же в модели для фильтрации прописал context_object_name = 'reviews_list'. После этого всё заработало как надо. Как я уже сказал, у меня немного другие названия, но суть вы поняли. Удачи!:)
Необходимо использовать distinct для year. При нескольких фильмах одного года, в фильтре будет повторение.
@DjangoSchool
4 жыл бұрын
Верно, хочу это показать в видео о рефакторинге
@user-lb1mg7ov6j
9 ай бұрын
@@DjangoSchool а где можно найти это видео ?
Лайк, лайк, лайк, лайк
Если фильмы одного года, все они и будут вываливаться в списке без группировки.
пересмотрел урок 5 раз, 2 раза повторил за тобой - у меня фильмы не выводятся(
Разве этот способ фильтрации не увеличивает время обработки запросов? При большой нагрузке на сервер это будет хорошо заметно, не лучше написать менеджеры для фильтров?
оно выводит отдельно и года и жанры, а как можно реализовать чтобы эти фильтры были вместе? К примеру если выбран 2020 год и жанр Боевики, то чтобы выводило Боевики 2020 года
@user-ld6yu6sv5r
2 жыл бұрын
def get_queryset(self): if 'genre' in self.request.GET and 'year' in self.request.GET: queryset = Movie.objects.filter( Q(year__in=self.request.GET.getlist("year")) , Q(genres__in=self.request.GET.getlist("genre")) ) else: queryset = Movie.objects.filter( Q(year__in=self.request.GET.getlist("year")) | Q(genres__in=self.request.GET.getlist("genre")) ) return queryset
а если мы жанр и год выбираем, но при этом у фильма год совпадает, жанр не совпадает то будет выводить всё равно, потому что одно из условий совпадает, а должно чтобы было логическое "И" при использовании обоих фильтров Вот как я сделал, что более правильно работает: if self.request.GET.getlist("genre") and self.request.GET.getlist("year"): queryset = Movie.objects.filter(year__in=self.request.GET.getlist("year"), genres__in=self.request.GET.getlist("genre")) else: queryset = Movie.objects.filter(Q(year__in=self.request.GET.getlist("year")) | Q(genres__in=self.request.GET.getlist("genre"))) Теперь работает правильно
Автор извини что не по тему. Ну вот в AUTH_USER_MODEL в settings.py можно только одну модель добавить ??
Добрый вечер на писать видео урок как на писать парсер для этого сайта. Чтобы не вбивать все в ручную
Мне кажется что у нас логика фильтрации скорее ближе к логическому И
В прошлом уроке мы передавали в шаблон actor.html контекст из класса ActorView и обращались к нему в шаблоне через actor (потому что указывали model = Actor, а context_object_name задан не был, ВЕРНО? ) В текущем уроке в шаблоне мы выводим жанры: {% for genre in view.get_genres %} ... Почему мы используем view для доступа к контексту??
@user-ie3dc3nc8l
3 жыл бұрын
Нашел ответ ниже. Про переменную view можно прочесть здесь: djbook.ru/rel1.9/ref/class-based-views/mixins-simple.html#contextmixin
@user-ie3dc3nc8l
3 жыл бұрын
Нет, всё таки не все понятно. Эта переменная view нужна в том случае, когда в шаблон не передается контекст непосредственно, и этот шаблон include-им в другой шаблон, и из него (из этого подключаемого шаблона) можно бы было обратиться к передаваемому контексту, верно? Я правильно понял? (если я конечно понятно задал вопрос)
@dmitriygribkov1272
Жыл бұрын
также не могу найти ответ. Ваша ссылка уже не работает, к сожалению
your course content seems awesome. but only problem is language. please if you could please make series on english . that would be so helpful . thank you
Всем привет! Возник вопрос, который, как я заметил, кто-то задавал два года назад, но так и не получил ответа. Может, сейчас кто-нибудь ответит - буду признателен. Когда мы выводим в цикле жанры, то используем переменную контекста view: {% for genre in view.get_genres %} Откуда она берется? Ведь мы не задаем ее в контроллере, не называем по имени модели, как в предыдущих уроках. Откуда же тогда появляется view
Так, а как сделать чтобы: - при выборе одного фильтра срабатывает поиск И - при выборе двух фильтров срабатывают оба, то есть год и жанр. Ведь если в query set поставить запятую то сработает только два фильтра, а по отдельности- нет.
@user-je5te5mf7u
4 жыл бұрын
узнал?
@Km-pn3hf
4 жыл бұрын
в общем, выбирайте свой вариант) stackoverflow.com/questions/62099463/django-filter-by-two-parameters
не вставляйте больше музыку никогда в жизни
добрый день, пробую сделать сортировку как у вас в ролике, но не помнимаю почему при наследование класса (где выводятся все категории ) данные не выводятся
@user-te5sk9sq4t
Жыл бұрын
Как вы решили проблему?
@user-rx4qq1tg1f
Жыл бұрын
@@user-te5sk9sq4t сделал через 2 массива и мержил их между собой, по сути я доставал по одной записи и потом собирал нужный мне объект
А есть видео где фильтр если выбрать год ,а потом написать имя фильма в поиск?
не получается найти ответ: при фильтрации берется шаблон, почему пытается подтянуть именно этот? : templates\movie\movie_list.html TemplateDoesNotExist at /filter/
@razdva1221
4 жыл бұрын
заработало после добавления template_name = "movies/movies.html" в класс: class FilterMoviesView(GenreYear, ListView):
@user-po7wm3zk5b
4 жыл бұрын
@@razdva1221 Спасибо, помог. У меня тоже открывало movie_list.html
А что делать, если у меня два разных фильтра и работает только то, чей path в url выше другого?
не знаю поздно или еще нет, но есть вопрос.. сейчас фильтрация идет через или: давай все фильмы или 1984 года или комедии (для примера), а если мне нужно такой отбор: дай мне только комедии 1984 года?
@DjangoSchool
4 жыл бұрын
Можно просто поменять логику фильтрации. Об этом будет урок.
@ASH-tc8lr
4 жыл бұрын
Тоже интересен данный вопрос, потому что сейчас работает как-то не очень: я выбираю боевики и 91 год а оно мне все боевики показывает. Если есть видео в котором это исправляеться хотелось бы узнать. Я пока что дошел до 18ю
Не понял, откуда у нас в {% for genre in view.get_genres%} view и что это вообще такое. Расскажите пожалуйста.
@andreisirbu4928
4 жыл бұрын
мы просто ссылаемся на наш метод (def get_years(self):), как раньше мы ссылались на нашу модель, к примеру movie, чтобы django знал откуда нам брать инфу. Уже в самой вьюшке мы выбираем фильмы которые не являются черновиком и получаем года этих фильмов
@user-rn8lo3sj4d
4 жыл бұрын
@@andreisirbu4928 Добрый день, такой же вопрос возник, разобрались с ним?
@olegmlavets5216
4 жыл бұрын
Тоже не понял откуда взялся обьект view
@user-ds2ie8ms5y
4 жыл бұрын
"view" у нас из context-а. В ContextMixin в методе get_context_data в context добавляют аттрибут "view"
@user-ds2ie8ms5y
4 жыл бұрын
А вот почему шаблон при фильтрации берется movie_list не сразу понял. Пришлось покопаться в коде.
{% url 'filter' %} не подскажете что это ? типо функция или класс
Если фильм принадлежит к нескольким жанрам, он выводится несколько раз. Как это исправить?
Возник вопрос, делаю фильтрацию, выводит более 20 элементов, но они не отображаются на страничке(когда писал вместо filter - get получал ошибку, что значений более 20)? как такое может получиться? благодарю
@DjangoSchool
4 жыл бұрын
А циклом в шаблоне вводишь?
@user-je5te5mf7u
4 жыл бұрын
@@DjangoSchool Естественно, уже решил, благодарю) Там траблы с листвью были) сделай как-нибудь стрим по оптимизации кода, пожалуйста) думаю людям будет интересно посмотреть на это)
@user-je5te5mf7u
4 жыл бұрын
@@DjangoSchool Писал через запросы без урлов, поэтому у меня пересеклись search_query и filter_query(
а почему не через пост идёт отправки просто коверкается url когда по get идёт запрос не красиво же выглядит пример : ( /?year=2003&year=2000&gener=1&gener=3 ) , можно это реализовать через пост ?
@DjangoSchool
4 жыл бұрын
Можешь реализовать через пост. Но мы получаем данные с сервера, поэтому гет запрос. А чем же юрл коверкается? Это параметры передаются. Часто обращаешь внимание на юрл когда ходишь по сайтам? (я без агрессии)
@cody__9115
4 жыл бұрын
Ну как видешь ), я просто спросил можно ли это через пост просто не думаю что многие хорошие сайты используя фильтрацию выражают все через get , но через пост же мы тоже получаем данные с сервера , или нет ?
@DjangoSchool
4 жыл бұрын
@@cody__9115 данные получаем через гет, посылаем через пост
@constlapkin
4 жыл бұрын
__ довольно частая практика при фильтрации «коверкание» урла
Можете подсказать почему могут не выводится никакие фильмы в этом поиске, что бы не делал ничего не появляется , нет ни ошибки ничего, подключаюсь на страничку список всех фильмов нижимаю/filter/?genre=3 пустой список
@DjangoSchool
4 жыл бұрын
Может нет записей которые бы поподали под условие фильтра?
А как сделать, что-бы чек-боксы не сбрасывались после поиска?
@DjangoSchool
4 жыл бұрын
Отправлять запрос ajax'ом или передавать после поиска в шаблон, какие были выбраны.
@igor_by
4 жыл бұрын
@@DjangoSchool В дальнейших уроках будет?
@DjangoSchool
4 жыл бұрын
@@igor_by Планировал когда буду делать api, но думаю можно будет сделать
@user-ew5fm7iq2e
4 жыл бұрын
selected добавить
почему-то он не хочет выводить в моем левом сайдбаре базового шаблона категорию товара, типы товара и брэнд(как показаны на видео жанры и года). Но когда я нажимаю на кнопку "Найти", он их выводит, но в совершенно другом шаблоне. В чем может быть проблема?
@DjangoSchool
3 жыл бұрын
Как реализован вывод, с помощью view или tags?
@Rabbit-9893
3 жыл бұрын
@@DjangoSchool с помощью view
@Rabbit-9893
3 жыл бұрын
@@DjangoSchool shop.html Категория {% for category in view.get_category %} {{ category.name }} {% endfor %} Типы {% for type in view.get_types %} {{ type.name }} {% endfor %} Бренд {% for brands in view.get_brands %} {{ brands.name }} {% endfor %} Цена {{ form.as_p}} Найти views.py from django.shortcuts import render from django.db.models import Q from django.core.paginator import Paginator from django.views.generic.base import View from django.views.generic import ListView, DetailView from .forms import FilterPrice from .models import Tovar, Category, Brands, Type class CategoryBrandsType: def get_category(self): return Category.objects.all() def get_brands(self): return Brands.objects.all() def get_types(self): return Type.objects.all() class FilterTovarView(CategoryBrandsType, ListView): def get_queryset(self): queryset = Tovar.objects.filter( Q(category__in=self.request.GET.getlist("category")) | Q(brands__in=self.request.GET.getlist("brands")) | Q(type__in=self.request.GET.getlist("type")) ).distinct() return queryset class TovarListView(CategoryBrandsType, ListView): #КЛАСС ВЫВОДА ТОВАРОВ def get(self, request): tovary = Tovar.objects.all()# form = FilterPrice(request.GET) if form.is_valid(): if form.cleaned_data["min_price"]: tovary = tovary.filter(price_tovar__gte=form.cleaned_data["min_price"]) if form.cleaned_data["max_price"]: tovary = tovary.filter(price_tovar__lte=form.cleaned_data["max_price"]) return render(request, "shop.html", {"tovar_list": tovary, "form": form}) urls.py from django.urls import path from .import views urlpatterns = [ path("", views.TovarListView.as_view()), path("filter/", views.FilterTovarView.as_view(), name='filter'), ]
@DjangoSchool
3 жыл бұрын
@@Rabbit-9893 как сложно тут читать код, думаю лучше написать к нам в группу в телеграм и код этот залить на pastbin
@Rabbit-9893
3 жыл бұрын
@@DjangoSchool хорошо
У меня два фильма с одним и тем же годом выпуска. В сайдбаре два раза рендерится один и тот же год, как это исправить?
@DmitrySakhno-xy5xf
4 жыл бұрын
в views: def get_years(self): years_sorted_list = sorted(set(Movie.objects.filter(draft=False).values_list('year', flat=True))) return years_sorted_list в sidebar: {% for year in view.get_years %} {{ year }} {% endfor %}
@user-zk3uo3ti6f
4 жыл бұрын
@@DmitrySakhno-xy5xf Трэш какой-то... distinct в конце queryset добавить можно и все. Примеры в документации docs.djangoproject.com/en/3.0/ref/models/querysets/#django.db.models.query.QuerySet.distinct
"{%for movie in view.get_years %}" не очень красиво выглядит лучше добавить "flat=True" в "values_list" stackoverflow.com/questions/37205793/django-values-list-vs-values#answer-37205928
@DjangoSchool
4 жыл бұрын
Отличное замечание, согласен. Но идея была показать что есть эти два метода. А так спасибо.
@intourist261
4 жыл бұрын
@@DjangoSchool привет, в файле sidebar, в цикле ничего не получаю через view.get_genres. В чем может быть ошибка? подскажи плиз.
@orxanzekiyev5177
3 жыл бұрын
я получил ошибку, которая говорит мне, что значение year 'on' при использовании метода get. (8:15 на видео) ..Field 'year' expected a number but got 'on'.. и не могу исправить
@igorgavr3460
Жыл бұрын
@@intourist261 тоже самое(
Можно было не применять другой метод, а написать {{ year.year }}
@symbolminded5167
3 жыл бұрын
А, ну там примерно такое же решение, сори