J'essaie de créer un formulaire de recherche simple pour les vues basées sur les classes avec Django. Tout semble fonctionner, sauf que le résultat de la recherche renvoie le modèle entier, donc évidemment la recherche / le filtre ne fonctionne pas. Je ne peux pas comprendre pourquoi après avoir lu un tas de tutoriels et de questions ici.

models.py:

class surveys(models.Model):
    FAN = models.SlugField(max_length=100, blank=True, null=True)
    Location = models.CharField(max_length=200, blank=True, null=True)

    def __str__(self):
        return self.FAN

    def get_absolute_url(self):
        return reverse('survey-detail', args=[str(self.FAN)])

views.py:

class Search(generic.ListView):
    template_name = 'datalibrary/search.html'
    model = surveys

    def get_queryset(self):
        try:
            name = self.kwargs['name']
        except:
            name = ''
        if (name != ''):
            object_list = self.model.objects.filter(FAN__icontains == name)
        else:
            object_list = ''
        return object_list

class SearchResults(generic.ListView):
    template_name = 'datalibrary/search_results.html'
    model = surveys

search.html:

{% extends "base_generic.html" %}

{% block content %}
    <form method="get" action="/results/" class="navbar-form pull-right">
        <input type="text" id="searchBox" class="input-medium search-query" name="search" placeholder="Search">
        <input type="submit" class="btn" value="Search" >
    </form>
{% endblock %}

search_results.html:

{% extends "base_generic.html" %}

{% block content %} 
    {{ object_list }}
{% endblock %}

urls.py:

urlpatterns +=[
    path('search/', views.Search.as_view(), name='search'),
    path('results/', views.SearchResults.as_view(), name='search-results'),
]

Une idée pourquoi object_list renvoie toutes les valeurs du modèle plutôt que de filtrer en fonction de l'entrée, même lorsqu'il n'y a pas d'entrée?

1
Evan 15 mars 2019 à 00:51

2 réponses

Meilleure réponse

Vous avez name = self.kwargs ['name'], qui n'obtient pas de 'name', pour rechercher une meilleure façon est de prendre le nom d'entrée comme requête et d'afficher les résultats.

class Search(generic.ListView):
    template_name = 'datalibrary/search.html'
    context_object_name = 'all_search_results'

    def get_queryset(self):
        result = super(Search, self).get_queryset()
        query = self.request.GET.get('search') #your input name is 'search'

        if query:
           object_list = surveys.objects.filter(FAN__icontains=query) #or FAN__contains
           result = object_list
        else:
           result = None    # When no result found

        return result

En Html,

{% extends "base_generic.html" %}

 {% block content %}
  <form method="get" action="/results/" class="navbar-form pull-right">
     <input type="text" id="searchBox" class="input-medium search-query" name="search" placeholder="Search">
     <input type="submit" class="btn" value="Search" >
  </form>



  {% for result in all_search_results %}
       {{result.add_according_to_the_model}}
  {% empty %}
        <p> No Results <p>
  {% endfor %}

   {% endblock %}

Vous pouvez afficher les résultats de la recherche sur la même page. Cependant, si cela est nécessaire pour vous, vous pouvez avoir différents html.

1
Bidhan Majhi 15 mars 2019 à 06:14

Vous recherchez quelque chose appelé self.kwargs['name'], mais votre vue ne contiendra aucun élément de ce type.

Premièrement, le nom de l'entrée de recherche dans votre code HTML est search, pas name.

Et deuxièmement, self.kwargs est pour les éléments qui sont capturés à partir de l'URL; mais celui-ci est envoyé sous forme de formulaire GET, vous devez donc l'obtenir à partir de la chaîne de requête: self.request.GET['search'].

Assembler, d'une manière un peu plus idiomatique:

def get_queryset(self):
    name = self.kwargs.get('name')
    object_list = self.model.objects.all()
    if name:
        object_list = object_list.filter(FAN__icontains == name)
    return object_list
1
Daniel Roseman 14 mars 2019 à 22:05