Code


Version 17 (modified by axiak, 6 years ago) (diff)

--

Autocompletion for ForeignKeys in Admin (YUI)

The Problem

In the Admin, I would like to have an autocompletion field for ForeignKey references. I know raw_id_admin works for foreign keys to big tables, but AJAX is just so much cooler.

The Solution

Using YUI, create a new field similar to models.ForeignKey that renders differently in the admin.

Installation

Here's how it's setup:

  1. Create a new folder in your project called ajaxfkey
  1. Put four files in that directory:
  1. Create a base_site.html file in your base_templates/admin directory.
  1. Modify your urls conf to contain the ajax view.
  1. Modify your models to use it correctly.

(top)

2.b Fixing fields.py

If you downloaded fields.py, you need to make sure the import line at the top correctly imports the Form field.

You might need to change this

from ajaxfkey.forms import AjaxForeignKeyFormField

to this

from myproject.ajaxfkey.forms import AjaxForeignKeyFormField

(top)

3. Creating base_templates/admin/base_site.html

Put the contents below in a place locatable by 'admin/base_site.html' in your setup. (It certainly does not need to be inside Django's source.)

{% extends "admin/base.html" %}
{% load i18n %}

{% block extrahead %}{{ block.super }}
<script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/dom/dom-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/connection/connection-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/animation/animation-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/autocomplete/autocomplete-min.js"></script>
<script type="text/javascript" src="http://www.json.org/json.js"></script>
{% endblock %}

{% block title %}{{ title|escape }} | {% trans 'Django site admin' %}{% endblock %}

{% block branding %}
<h1 id="site-name">{% trans 'Django administration' %}</h1>
{% endblock %}

{% block nav-global %}{% endblock %}

(top)

4. Modify urls.py

Put the following in your urls configuration:

(r'^admin/ajax_autocomplete/?', 'project.ajaxfkey.views.ajax_autocomplete'),

Change project.ajaxfkey to the path to the views file you created.

(top)

5. Using it in your models

To use, you need to define a ajax_autocomplete(data) (either in Model or Model.objects) and an ajax_str.

Below is an example usage in some models:

from django.db import models
from ajaxfkey.fields import AjaxForeignKey

# notice the manager, we can create a staticmethod in Poll if we wanted.
class PollManager(models.Manager):
    def ajax_autocomplete(self, data):
        return self.filter(question__istartswith = data).order_by('question')

class Poll(models.Model):
    question = models.CharField(maxlength=200)
    pub_date = models.DateTimeField('date published')

    # set the manager
    objects = PollManager()

    # this is how it displays in the autocompletion...should be related to 
    # how the person filters above
    def ajax_str(self):
        return self.question

class Choice(models.Model):
    # notice it's the same syntax as models.ForeignKey
    poll = AjaxForeignKey(Poll)
    choice = models.CharField(maxlength=200)
    votes = models.IntegerField()

(top)

Screenshot

Congratulations, you should be done! The obligatory screenshot is:

http://esp.mit.edu/media/uploaded/07_05/ajaxfkey.jpg

Problems

If you have any problems, feel free to email me at http://mike.axiak.net/contact/

Attachments (4)

Download all attachments as: .zip