2

I have two models: Director, and Film.

I want to create a web query form so that a user can search something like "All films from director 'Steven Spielberg' between 1990 and 1998".

Just curious what the best and simplest way to do this would be?

Thanks,

Sam Starling
  • 5,298
  • 3
  • 35
  • 52
thedeepfield
  • 6,138
  • 25
  • 72
  • 107

3 Answers3

6

OK the simplest solution is something like that.

I make some assumptions about the structure of your models, so adjust accordingly.

Let's say this is our models.py

from django.db import models

class Director(models.Model):
    name = models.CharField(max_length=128)
    # maybe some other fields...

class Film(models.Model):
    title = models.CharField(max_length=128)
    director = models.ForeignKey(Director)
    created_at = models.DateField()

Our naive views.py Please keep in mind that I deliberately omit many sanity checks.

import datetime
from django.shortcuts import render_to_response
from myapp.models import Film

def search(request):
    # Suppose we support these params -> ('director', 'fromdate', 'todate')
    request_params = request.GET.copy()
    fromdate = datetime.datetime.strptime(request_params['fromdate'], 'some-string-format')
    todate = datetime.datetime.strptime(request_params['todate'], 'some-string-format')
    # Our query is ready to take off.
    film_results = Film.objects.filter(
        director__name=request_params['director'],
        created_at__range=(fromdate, todate)
    )
    return render_to_response('search_results.html', {'results':film_results})

Our search_results.html template

{% extends some_base.html %}
{% if results }
  {% for film in results %}
    <h3>{{ film.title }}</h3>
    <p>Director: {{ film.director.name }}</p>
    <p>When: {{ film.created_at }}</p>
  {% endfor %}
{% else %}
  <p>Sorry no results for your query</p>
{% endif %}

Also read this on creating datetime objects from string

Edit: Oh I forgot about the urls.py and the actual form :)

in your url.py add something like this inside the urlpatterns.

url(r'^search/$', 'myapp.views.search'),

Now the actual search form must be something like this:

<form method='GET', action='/search/'>
... your fields
</form>

You can generate it through a django form if you wish. Anyway this is not going to get you far I guess. If you are doing anything serious you might take a look into haystack

Community
  • 1
  • 1
rantanplan
  • 7,283
  • 1
  • 24
  • 45
  • Hmm, I was hoping I wouldn't have to do all this... what happens if the End-User only selects dates, and no author? will the query just pull all books from like 1990 to 1998? – thedeepfield Apr 30 '12 at 21:20
  • Well the things you mention are the sanity checks that I deliberately ommited :) But how could you automate this? The logic you described can't be inferred without inflexible assumptions. The only thing that needs discussing/thinking is where to put that logic. Inside the view or maybe your search form? You decide. – rantanplan Apr 30 '12 at 21:28
1

Hm. I don't believe any utilty like this exists. It would be nice if there were a reverse ModelForm. It would look at field type and get the data ranges for each field for a search form.

I think right now you are stuck with creating a text box and a datepicker range. And processing that data in a view.

dm03514
  • 54,664
  • 18
  • 108
  • 145
0

Sounds like you want to let your users perform "faceted" searches. Django Haystack will let you do that. Their documentation contains information about faceting.

Sam Starling
  • 5,298
  • 3
  • 35
  • 52