= !AjaxForeignKey Field =
== The Problem ==
In the Admin, I would like to have an autocompletion field for !ForeignKey references. I know raw-id-admin works, but AJAX is just so much cooler.
== The Solution ==
=== Overview ===
Using [http://developer.yahoo.com/yui/ 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 }}}
2. Put four files in that directory:
* {{{__init__.py}}} -- duh
* {{{fields.py}}} -- contains the actual model field. (download)
* {{{forms.py}}} -- contains the form field. (download)
* {{{views.py}}} -- contains the AJAX view. (download)
3. Create a {{{base_site.html}}} file in your {{{base_templates/admin}}} directory.
4. Modify your {{{urls conf}}} to contain the ajax view.
5. Modify your models to use it correctly.
=== Creating {{{ base_templates/admin/base_site.html }}} ===
Put the contents below in the file, but be wary of where yui is on your setup.
{{{
{% extends "admin/base.html" %}
{% load i18n %}
{% block extrahead %}{{ block.super }}
{% endblock %}
{% block title %}{{ title|escape }} | {% trans 'Django site admin' %}{% endblock %}
{% block branding %}
{% trans 'Django administration' %}
{% endblock %}
{% block nav-global %}{% endblock %}
}}}
Notice how YUI is in {{{"/media/scripts/yui"}}} and I downloaded [http://www.json.org/json.js json.js].
=== Modify {{{urls.py}}} ===
Put the following in your urls configuration:
{{{
#!python
(r'^admin/ajax_autocomplete/?', 'project.ajaxfkey.views.ajax_autocomplete'),
}}}
Change {{{project.ajaxfkey}}} to the path to the views file you created.
=== 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:
{{{
#!python
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')
# 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()
}}}
=== Screenshot ===
Congratulations, you should be done! The obligatory screenshot is:
http://esp.mit.edu/media/uploaded/07_05/ajaxfkey.jpg