简体   繁体   中英

Search in django doesn't work

I am trying to have search option i my page. I have tried the method given in the standard django document in this link ' https://docs.djangoproject.com/en/1.11/intro/tutorial01/ ', but my search function isn't working. only the url changes from http://localhost:8000/contact this to http://localhost:8000/contact/your-contact/?q=harini but datas are not filtered and displayed. I am using django 1.11. Could anyone help me with it? Thanks in advance

models.py

from __future__ import unicode_literals

from django.db import models

class ContactModel(models.Model):
    name = models.CharField(max_length=200)
    dob = models.DateField()
    phone_number = models.IntegerField()
    gender = models.BooleanField()
    address = models.CharField(max_length=200)

views.py

from __future__ import unicode_literals

from django.shortcuts import render

from django.http import HttpResponseRedirect, HttpResponse
from django.views import generic
from django.template.response import TemplateResponse

from django.views.generic import CreateView
from django.urls import reverse_lazy
from .models import ContactModel
from .forms import ContactForm

class ContactView(CreateView):
    model_class = ContactModel
    form_class = ContactForm
    success_url = reverse_lazy('contact-thanks')
    initial = {'name': 'value'}
    template_name = 'contact/contact.html'

    def get(self, request, *args, **kwargs):
        model = self.model_class()
        return render(request, self.template_name, {'model': ContactForm})

    def post(self, request, *args, **kwargs):
        if request.method == 'POST':
            form = ContactForm(request.POST)
            if form.is_valid():
                form.save()
                return HttpResponseRedirect('thanks/')

            else:
                form = ContactForm()

                return render(request, 'contact.html', {'form': form})

class ContactlistView(CreateView):
    model = ContactModel
    template_name = 'contact/contactlist.html'

    def search(request):
        query = request.GET['q']
        t = loader.get_template('template/contact/contactlist.html')
        c = Context({ 'query': query,})

        if query:
            results = Contact.objects.filter(Q(name__icontains=query) |
                                             Q(dob__icontains=query) |
                                             Q(address__icontains=query) |
                                             Q(gender__icontains=query) |
                                             Q(phone_number__icontains=query))

            return render(request, 'contactlist.html', {'form': form})

        else:
            return render(request, 'contactlist.html', {'form': form})

urls.py

    from django.conf.urls import url

from . import views

app_name = 'contact'

urlpatterns = [
    url(r'^$', views.ContactView.as_view(), name='contact'),
    url(r'^your-contact/$', views.ContactView.as_view(), name='contact'),
    url(r'^your-contact/thanks/$', views.ContactView.as_view(), name='contact'),
    url(r'^contact-list/$', views.ContactlistView.as_view(), name='contactlist'),
    url(r'^contact-list/your-contact/$', views.ContactlistView.as_view(), name='contactlist'),
]

templates/contact/contactlist.html

<form method="get" action="contact-list/">
  <input type="text" id="searchBox" class="input-medium search-query" name="q" placeholder="Search" value= "{{ request.GET.q }}">
  {% if contact %}
  {% for each_contact in contacts %}
  <h3>Name: {{ contact.name }}</h3>
  <p>Dob: {{ contact.dob }}</p>
  <p>Gender: {{ contact.gender }}</p>
  <p>Address: {{ contact.address }}</p>
  <p>Phone Number: {{ contact.phone_number}}</p>
  {% endfor %}
  {% endif %}
  <input type="submit" class="btn" value="Search" >
</form>

Your form action is pointed to your-contact/

<form method="get" action="your-contact/">

So this URL calls the view ContactView() , whereas the search query process is in the ContactlistView() view

class ContactlistView(CreateView):
     ''' '''
    def search(request):
        query = request.GET['q']

A solution is: a little edit in your URLs patterns:

 url(r'^contact-list/$', views.ContactlistView.as_view(), name='contactlist'),

And change the form action url and point it to this view ContactlistView(): with contact-list/

<form method="get" action="contact-list/">

Don't forget to replace if q: with if query:

I think the view as you have it right now is doing nothing, you should modify it in:

class ContactlistView(CreateView):
    model = ContactModel
    template_name = 'contact/contactlist.html'

    def get(self, request):
        query = request.GET['q']
        t = loader.get_template('template/contact/contactlist.html')
        c = Context({ 'query': query,})

        if query:
            results = Contact.objects.filter(Q(name__icontains=query) |
                                             Q(dob__icontains=query) |
                                             Q(address__icontains=query) |
                                             Q(gender__icontains=query) |
                                             Q(phone_number__icontains=query))

            return render(request, 'contactlist.html', {'form': form})

        else:
            return render(request, 'contactlist.html', {'form': form})

Also please note a couple of things:

  • you're inheriting froma CreateView but you are not creating anything and you are not getting any advantage from that view, you should use a GenericView instead
  • you're defining the template as class attribute but then you are rendering you are doing everything manually because you are not getting (again) advantage of the CBV

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM