Алдыңғы мақалаларда біз сайтта сайт іздеуді қалай жасауға болатынын қарастырдық. Атап айтқанда:
- Жүзеге асыру сайтта сұралды
- Қосымша іздеу опциялары
- Аргументтер тізімін QuerySet сұрыптаудың реті бойынша әдісіне беру
Бірақ егер сізде бірнеше мазмұн түрі болса ше? Сізде мақалалар, пікірлер, форум және форум жазбалары болуы мүмкін. Сонда қалай болу керек?
Егер сіз үшінші тарап кітапханаларын пайдаланбай, бәрін өзіңіз жасағыңыз келсе, барлық қажетті үлгілерді іздеп, нәтижені біріктіруіңіз керек. Мен сайтта дәл солай жасадым.
urls.py
Сізге іздеу сұрауын өңдейтін бір Көрініс сыныбы қажет болады.
Мұндағы маңызды мәселе - пайдаланушылар іздеу нәтижелерімен сілтемелерді бөлісе алуы үшін біз тарту сұрауларын өңдейміз.
urls.py файлында іздеу маршрутын жазамыз
app_name = 'home' urlpatterns = [ path('search/', views.SearchView.as_view(), name='search'), ]
рет көру.py
Бізде бірнеше мазмұн түрі бар делік:
- Мақала
- Пікір
- Тақырып
- Пост
Көріністе мазмұнның барлық түрлерін іздеу және оларды бір QuerySet жиынтығына біріктіру және беттеу мен жеткізуге дайындалу қажет
from itertools import chain from django.shortcuts import render from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage from django.views import View from .models import Article, Comment, Topic, Post class ESearchView(View): template_name = 'search/index.html' def get(self, request, *args, **kwargs): context = {} q = request.GET.get('q') if q: query_sets = [] # Total QuerySet # Searching for all models query_sets.append(Article.objects.search(query=q)) query_sets.append(Comment.objects.search(query=q)) query_sets.append(Topic.objects.search(query=q)) query_sets.append(Post.objects.search(query=q)) # and combine results final_set = list(chain(*query_sets)) final_set.sort(key=lambda x: x.pub_date, reverse=True) # Sorting context['last_question'] = '?q=%s' % q current_page = Paginator(final_set, 10) page = request.GET.get('page') try: context['object_list'] = current_page.page(page) except PageNotAnInteger: context['object_list'] = current_page.page(1) except EmptyPage: context['object_list'] = current_page.page(current_page.num_pages) return render(request=request, template_name=self.template_name, context=context)
Жоғарыдағы кодтың нюансы мынада: біз барлық деректер үлгілерін біріктіріп, оларды күні бойынша сұрыптаймыз. Мұны мүмкін ету үшін біз Python бағдарламалау тілінің мүмкіндіктерін, атап айтқанда үйрекпен теруді қолданамыз. Күні бойынша сұрыптау барлық деректер үлгілерінде бірдей атаумен pub_date жарияланған күні өрісінің болуымен мүмкін болады.
Жалпы, бұл деректер үлгісі өрістерін әртүрлі деректер үлгілері үшін бірдей атауға тырысқанда өте маңызды. Бұл сізге Django сайтын әзірлеуде өте икемді болуға және белгілі бір деректер түріне тәуелді емес, керісінше деректер үлгілері қолдайтын интерфейске байланысты деректерді көрсетуге арналған үлгілерді жазу үшін үйрек теруді пайдалануға мүмкіндік береді.
Бұл кодта ұсынылған барлық деректер үлгілерінің нысандарында бірдей іздеу әдісі бар екені де қызық. Бұл әдіс стандартты емес. Оны жүзеге асыру үшін сіз өзіңіздің үлгі менеджеріңізді жазып, оны нысан өрісіне тағайындауыңыз керек.
Мақала менеджері
Әдеттегі мақала менеджерін қарастырыңыз. Біз оны негізгі үлгі менеджерінен мұраға аламыз және іздеу логикасын пайдаланып іздеу әдісін анықтаймыз. Сол сияқты, іздеу орындалатын барлық үлгілер үшін осы әдісті тіркеу қажет.
from django.db import models from django.db.models import Q class ArticleManager(models.Manager): use_for_related_fields = True def search(self, query=None): qs = self.get_queryset() if query: or_lookup = (Q(title__icontains=query) | Q(content__icontains=query)) qs = qs.filter(or_lookup) return qs
Үлгіде менеджерді орнату
class Article(models.Model): objects = ArticleManager()
іздеу/index.html
Ал іздеу үлгісі үшін іздеуді ұйымдастыру туралы алғашқы мақалалардың біріндегі сәл өзгертілген үлгіні пайдалануға болады.
{% load bootstrap34%} {% block page %} <h1>Поиск</h1> {% if object_list %} {% for object in object_list %} <div> <a href="{{ object.get_absolute_url }}"> <h2>{{ object.itle }}</h2> </a> {{ object.content|safe }} <p><a class="btn btn-default btn-sm" href="{{ object.get_absolute_url }}">Читать далее</a></p> </div> {% endfor %} {% bootstrap_pagination object_list url=last_question %} {% else %} <p>Не найдено публикаций по вашему запросу<br>Попробуйте повторить запрос с другой формулировкой</p> {% endif %} {% endblock %}
Мен бұл жағдайда арнайы мазмұн түрінің көрсеткіші жоқ анонимделген нысан параметрін қолданамын, сондықтан кез келген мазмұн нысаны болуы мүмкін екені анық болды. Ең бастысы, барлық әдістер осы үлгіде қолданылатын барлық модельдер үшін жүзеге асырылады.
Исправьте код в views.py, пропущен импорт chain из itertools.
Спасибо! Исправил.
Добрый день, небольшая проблемка с пагинацией, отображается информация только на первой странице при переходе на другую - пустая страница, views, models.Manager, шаблон, все сделал как в данном уроке, подставил только свои значения. Подскажите, в чем может быть проблема?
Спасибо.
Добрый день.
Покажите ваш код... Невозможно понять, где вы допустили ошибку, не видя, что вы делали.
Когда будете добавлять код в сообщение, используйте диалог вставки программного кода, одна из кнопок в тулбаре редактора комментариев. Тогда будет добавлена соответствующая разметка для блоков кода.
Опечатка в статье. Напишите так
И на старуху бывает проруха. Спасибо за вопрос.
Если бы не просмотрел ваш код, то скорее всего не заметил бы опечатку
Спасибо, Евгений, все заработало. Хороший сайт.
Спасибо за отзыв. Не стесняйтесь задавать вопросы. Только у меня убедительная просьба, все вопросы или на форуме сайта, или в комментариях к статьям. Чтобы потом у других пользователей было больше шансов найти ответ. Также на форуме присутствуют и другие опытные специалисты, они вполне могут тоже что-то подсказать, так что шансы получить ответ будут выше.
Здравствуйте, небольшой вопрос,
при добавлении формы пагинатора левая крайняя кнопка назад "<<" постоянно смещена вверх, относительно ряда цифр, не могу ее никак выровнять, в чем может быть проблема?
{% bootstrap_pagination object_list url=last_question %}
Хотел установить пагинатор прописав код, но немного запутался с адресами между страниц.
Подскажите, как правильно прописать адреса.
Спасибо.
У вас есть ещё какие-то кастомные стили, которые могут влиять на "<<", поскольку у меня такой проблемы не наблюдалось.
Ну по идее, это как-то тако должно выглядеть
Добрый день, Евгений,
сработал вот такой вариант:
href="?q={{ question }}&page={{ object_list.previous_page_number }}"
и во views добавил:
context['question'] = q
По поводу формы пагинатора, пробовал отключать все дополнительные стили, все также вылезает ошибка. Подумаю еще над этим, главное что есть рабочий вариант.
Спасибо за подсказку.