= !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 === 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') 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