Реализация фильтров поиска в Django
Хочу реализовать поле поиска с возможностью выбора фильтров поиска, возможно ли это реализовать силами Django и Python, JS не знаю, но если без него никак, буду рад помощи в написании? Теперь к делу: У меня уже реализован полнотекстный поиск и к нему хочу добавить фильтры Мой файл Views
class HomeView(ListView):
"""
This is our home page
"""
template_name = 'main_page/index.html'
model = Person
class SearchPageView(ListView):
"""
This is our search page
"""
template_name = 'main_page/search.html'
model = Person
class SearchResView(ListView):
"""
Search results will be here
"""
model = Person
template_name = 'main_page/search_res.html'
paginate_by = 2
def get_queryset(self):
"""
Search fild functional realisation
input data: str
return: ur Model object with ur input params else None
"""
query = self.request.GET.get('q')
object_list = Person.objects.filter(
Q(first_name__icontains=query) | Q(last_position__icontains=query)
)
return object_list
def get_context_data(self, **kwargs):
"""
The same as previous but it needs for
Functional implementation required for pagination
"""
context = super().get_context_data(**kwargs)
context['query'] = self.request.GET.get('q')
return context
class PersonView(DetailView):
"""
Full info link realisation
"""
model = Person
template_name = 'main_page/person_view.html'
context_object_name = 'person_item'
Шаблоны
search.html - страница на которой находится кнопка поиска
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Search</title>
<link rel="stylesheet" href="{% static 'main_page/css/search.css'%}">
<link rel="stylesheet" href="{% static 'main_page/css/sidebar.css'%}">
<link rel="stylesheet" href="{% static 'main_page/css/footer.css'%}">
<link rel="stylesheet" href="{% static 'main_page/css/pagination.css'%}">
<link rel="stylesheet" href="{% static 'main_page/css/table.css'%}">
</head>
<body>
<!--header-->
<div class='general'>
<nav class="nav">
<div class="logo">
ITI<strong style="color: #153b66; font-weight: 800">VA</strong>
</div>
<ul class="links">
<li class="list">
<a href="{% url 'home' %}">Homepage</a>
<div class="home_underline"></div>
</li>
{% if user.is_authenticated %}
<li class="list">
<a href="{% url 'logout' %}">Logout</a>
<div class="home_underline"></div>
</li>
{% else %}
<li class="list">
<a href="{% url 'signup' %}">Signup</a>
<div class="home_underline"></div>
</li>
<li class="list">
<a href="{% url 'login' %}">Login</a>
<div class="home_underline"></div>
</li>
{% endif %}
<button class="btn-1">CONTACT</button>
</ul>
<label form="nav-toggle" class="icon-burger">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</label>
</nav>
<div class="govno">
<!--sidebar-->
{% block sidebar %}
<div class="sidebar">
<form action="{% url 'search_res' %}" method="get">
{% csrf_token %}
<input type="text" id="searchbar" value="" placeholder="Search here..." required class="search_input"
name="q">
<button type="submit" class="search_btn">
<img src="{% static 'images/search.svg' %}">
</button>
</form>
</div>
{% endblock %}
{% block table %}
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu eleifend sapien. Donec eget turpis sed
turpis hendrerit malesuada. Morbi pellentesque rutrum nisi a mollis. Ut congue eros convallis nibh
vestibulum, at euismod urna commodo. Quisque tempor sapien dictum eros sagittis consequat. Sed vitae viverra
ligula. In aliquet volutpat leo sed consectetur. Maecenas quis tellus sapien. Curabitur vitae quam quis
augue condimentum auctor quis nec nisi.
</p>
{% endblock %}
</div>
<!--footer-->
<footer id="footer" class="footer-1">
<div class="main-footer">
<div class="containers">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-3">
<div class="widget subscribe no-box">
<h5 class="widget-title">ITIVA<span></span></h5>
<p>Something about ITIVA.. </p>
</div>
</div>
<div class="footer-copyright">
<div class="containers">
<div class="row">
<div class="col-md-12 text-center">
<p>Copyright ITIVA © 2022. All rights reserved.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</footer>
</div>
</body>
</html>
search_res.html страница с результатами поиска
{% extends 'main_page/search.html' %}
{% block table %}
<div class="container">
<table>
<thead>
<tr>
<th>First_name</th>
<th>Surname</th>
<th>Url</th>
<th>Location</th>
<th>Last_position</th>
<th>Full info</th>
</tr>
</thead>
<tbody>
{% for object in object_list %}
{% if object_list %}
<tr>
<td>{{ object.first_name }}</td>
<td>{{ object.surname }}</td>
<td>{{ object.url }}</td>
<td>{{ object.location }}</td>
<td>{{ object.last_position }}</td>
<td>
<a href="{{ object.get_absolute_url }}">View full info</a>
</td>
</tr>
{% else %}
<h1>Nothing to search...</h1>
{% endif %}
{% endfor %}
</tbody>
</table>
{% if page_obj.has_other_pages %}
<nav data-pagination>
<ul>
{% for p in page_obj.paginator.page_range %}
{% if page_obj.number == p %}
<li class=current><a href="/search_res?page={{ p }}&q={{ query }}">{{ p }}</a>
{% elif p > page_obj.number|add:-3 and p < page_obj.number|add:3 %}
<li><a href="/search_res?page={{ p }}&q={{ query }}">{{ p }}</a>
{% endif %}
{% endfor %}
</ul>
</nav>
{% endif %}
</div>
{% endblock %}
Файл models.py
from django.db import models
from django.urls import reverse
class Person(models.Model):
"""
Our general model
"""
first_name = models.CharField(max_length=150)
surname = models.CharField(max_length=150)
url = models.CharField(max_length=500)
location = models.CharField(max_length=150)
last_position = models.CharField(max_length=150)
def get_absolute_url(self):
return reverse('person_view', kwargs={'pk': self.pk})
def __str__(self):
return self.first_name
class Meta:
ordering = ['first_name']
class Education(models.Model):
"""
Person education table
This table are inherited from Person table
"""
person = models.ForeignKey('Person', on_delete=models.CASCADE)
university = models.CharField(max_length=150)
degree = models.CharField(max_length=150)
info = models.CharField(max_length=150)
admission_date = models.DateField()
graduation_date = models.DateField()
class Experience(models.Model):
"""
Person Experience table
This table are inherited from Person table
"""
person = models.ForeignKey('Person', on_delete=models.CASCADE)
company = models.CharField(max_length=150)
position = models.CharField(max_length=150)
hiring_date = models.DateField()
fired_date = models.DateField()
job_location = models.CharField(max_length=150)
description = models.CharField(max_length=150)
Я пробовал с django-filter, но то ли я что-то не так делал, то ли так и должно быть, но у меня под каждый критерий поиска был просто новый searchbar типа инпут, что не очень подходит по семантике
P.S. Я мог не совсем корректно изложить свою мысль, поэтому продублирую, что я хочу иметь одно поле ввода запроса поиска и под ним фильтры запроса