javascriptpythonjquerydjangoimdbpy

Creating an autocomplete search form (probably w/ jQuery) using a comprehensive (huge) movie title list (Django project) from IMDBPy


I am in the early stages of retrieving IMDB data via the Python package IMDBPy (their site) (proj github). I have been referring to this nice IMDBPy implementation for help with aspects of what I'm doing here. Several of the queries that I'm using generate datasets that come in "nested dictionary" form, e.g. 'movie_1':{'title':'One Flew Over the Cuckoo's Nest', 'director': 'Milos Forman'...}. My early version of the title retrieval takes this form in VIEWS.PY:

def index(request):
    imdb = IMDb()
    test_movies = {}
    for i in range(1100000, 1100015):
        test_movies[f'movie_{i}'] = imdb.get_movie(f'{i}')
    context = {
        'test_movies':test_movies,
    }
    return render(request, 'index.html', context)

And this in my INDEX.HTML template:

<div id="search-part1">
  <ul>
    {% for k1,v1 in test_movies.items %}
    {% for k2,v2 in v1.items %}
    {% if 'title' in k2 %}
    <li>{{v2}}</li>
    {% endif %}
    {% endfor %}
    {% endfor %}
  </ul>
  <input type="text" name="search" id="search" class="form-control" placeholder="Search for Movies">
</div>

Right now, the HTML is just to show that I *can generate a list of these titles. My actual implementation of the dropdown from the search bar (via jQuery's Autocomplete), is a little further down the road at this point. Here is an example that they provide of the Autocomplete in action, in the jQuery documentation:

<script>
  $( function() {
    var availableTags = [
      "ActionScript",
      "AppleScript",
      "Asp",
      "BASIC",
      "C",
      "C++",
      "Clojure",
      "COBOL",
      "ColdFusion",
      "Erlang",
      "Fortran",
      "Groovy",
      "Haskell",
      "Java",
      "JavaScript",
      "Lisp",
      "Perl",
      "PHP",
      "Python",
      "Ruby",
      "Scala",
      "Scheme"
    ];
    $( "#tags" ).autocomplete({
      source: availableTags
    });
  } );
  </script>

Essentially, at this stage, I want to draw up a massive list of all possible movie titles, and narrow that down based upon the first few letters that a user enters for a title search. Five or six of those need to appear for the purposes of the autocomplete drop-down underneath the search bar.

So, yes, there are a lot of moving parts to this. There is the slice of the huge, huge movie title database, which we filter out using the first few letters that the user types in. At some point, the var array that appears in the jQ section of the HTML needs to get populated with the values that will be shown in the drop-down autocomplete. I'm not sure how large that array can be within the HTML template before it becomes totally unwieldy, visually, or performance-wise. I don't know if these various components of a Django project can interact so dynamically, and quickly. I don't know if I'm taking a reasonable approach to achieving my goals with this stage of the project.

Any tips at all for the entirety or even a portion of what I'm undertaking would be much appreciated!

Edit: We haven't gotten to Ajax yet in my bootcamp curriculum. Guess it might be just the thing for easily/dynamically transferring stuff from a large database to the front end, eh?

Edit 2: Perhaps I should be trying to format the IMDB data, which comes as a dictionary of dictionaries, to JSON? Would that work better with the data translation? I have not worked too much with JsonResponse or other json-related packages.


Solution

  • You are iterating over k1, v1 of a dict with the format {'movie_1100000': <Movie Object>}

    Then you iterate over the keys and values k2, v2 of the Movie instance (which behaves like a dict) From there, you filter only the k2 keys which contains 'title'; there are various, like 'title', 'canonical title', 'long imdb canonical title' and various others (see the _additional_keys method of the Movie class). And then you print its value.

    Apparently it's not possible by default to directly access a key in a Django template, so you have to iterate over each key and find the exact match you want.

    This should work:

    <div id="search-part1">
      <ul>
        {% for k1,v1 in test_movies.items %}
        {% for k2,v2 in v1.items %}
        {% if k2 == 'title' %}
        <li>{{v2}}</li>
        {% endif %}
        {% endfor %}
        {% endfor %}
      </ul>
      <input type="text" name="search" id="search" class="form-control" placeholder="Search for Movies">
    </div>