Применить фильтр для поиска в django - PullRequest
0 голосов
/ 14 февраля 2020

Я хочу найти имя пользователя в базе данных и перечислить все результаты поиска на другой странице. На этой странице, к перечисленным результатам, я хочу применить некоторую фильтрацию. Это звучит как простая вещь, но я испытываю трудности. Я использую django -фильтры.

в доме . html У меня есть поиск

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Home</title>
</head>
<body>
<form action = {% url 'users:index' %} method="get">
    {% csrf_token %}

        <div class="d-flex justify-content-center">
            <div>
                <input class="form-control" type="text" name="search"
                       placeholder="Search a user...">
            </div>
            <div>
                <button class="btn btn-dark" type="submit" name="action">Search</button>
            </div>
        </div>
</form>
</body>
</html>

Результаты перечислены в индексе . html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Users App</title>
</head>
<body>

<form method="GET">
    {{ filter.form }}
    <button type="submit" >Search</button>
</form>
{% if filter.qs %}
    <ul>
    {% for user in filter.qs %}
        <li><a href="{% url 'users:detail' user.id %}">{{ user.name }}, {{ user.nationality }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No users available.</p>
{% endif %}
</body>
</html>

Теперь, если я попытаюсь применить фильтр от filter.form, я получаю ошибку Невозможно использовать None в качестве значения запроса. Вот views.py :

# Create your views here.
def home(request):
    return render(request, 'users/home.html')

class UserListView(ListView):
    model = User
    template_name = 'users/index.html'
    # queryset = User.objects.filter(name__icontains='Bruno') same as
    def get_queryset(self):  # new
        query = self.request.GET.get('search')
        return User.objects.filter(name__icontains=query)
    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        context['filter'] = UserFilter(self.request.GET, queryset=self.get_queryset())
        return context

urls.py

app_name = 'users'
urlpatterns = [
    path('home/', views.home, name='home'),
    path('', views.UserListView.as_view(), name='index'),
    path('<int:user_id>/', views.detail, name='detail'),
]

filters.py

import django_filters as filters
from .models import User
class UserFilter(filters.FilterSet):
    class Meta:
        model = User
        fields = ('name', 'surname',)

проблема заключается в том, что после поиска, отправленного методом POST, при повторном использовании представления UserListView команда self.request.GET.get('search') возвращает пустой объект.

Как мне отфильтровать результаты поиска? Есть ли способ сохранить поисковый запрос, чтобы фильтр применялся только к найденным элементам?

Ответы [ 2 ]

0 голосов
/ 14 февраля 2020

Если ваше представление результатов также имеет те же поля фильтрации, то вы можете просто снова передать ранее использованные параметры этому представлению.

Примерно так:

views.py

def results_view(request):
    results = []
    # Your search/filtering code here...
    query = request.GET.get('query')
    return render(request, 'results.html', {
        'results': results,
        'query': query
    })

Результаты. html

<form>
    <input name="query" value="{% if query %}{{ query }}{% endif %}" />
</form>
0 голосов
/ 14 февраля 2020

Для ошибки «Невозможно использовать None в качестве значения запроса» вы можете обновить get_queryset(), чтобы проверить, нет или пустых значений.

def get_queryset(self):
    query = self.request.GET.get('search')
    if query:
        return User.objects.filter(name__icontains=query)
    else:
        return User.objects.none()  # or .all() depending on what you want to show
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...