= 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 [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 '''forms2.py''' and rename) * {{{views.py}}} -- [#OneLastThing contains the AJAX view. (download) ] 3. [#Creatingbase_templatesadminbase_site.html Create a base_site.html file in your base_templates/admin directory.] 4. [#Modifyurls.py Modify your urls conf to contain the ajax view.] 5. [#Usingitinyourmodels Modify your models to use it correctly.] === 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 }} {% endblock %} {% block title %}{{ title|escape }} | {% trans 'Django site admin' %}{% endblock %} {% block branding %}

{% trans 'Django administration' %}

{% endblock %} {% block nav-global %}{% endblock %} }}} === 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') # 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() }}} === One Last Thing === 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 {{{ #!python from ajaxfkey.forms import AjaxForeignKeyFormField }}} to this {{{ #!python from myproject.ajaxfkey.forms import AjaxForeignKeyFormField }}} === 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://www.axiak.net/contact/