Code


Version 6 (modified by Michael Axiak <axiak@…>, 7 years ago) (diff)

Added my contact info

Autocompletion for ForeignKeys in Admin

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 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:
  • __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)
  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.

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 }}
<script type="text/javascript" src="/media/scripts/yui/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="/media/scripts/yui/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="/media/scripts/yui/dom/dom-min.js"></script>
<script type="text/javascript" src="/media/scripts/yui/connection/connection-min.js"></script>
<script type="text/javascript" src="/media/scripts/yui/animation/animation-min.js"></script>
<script type="text/javascript" src="/media/scripts/yui/autocomplete/autocomplete-min.js"></script>
<script type="text/javascript" src="/media/scripts/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 %}

Notice how YUI is in "/media/scripts/yui" and I downloaded json.js.

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.

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

    # 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

Problems

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

Attachments (4)

Download all attachments as: .zip