In the Django admin interface there is the nice ability to dynamically add new items to foreign key fields and it'd be nice to provide that same functionality in our own interfaces. Luckily since the admin interface already has all the functionality implemented we can be good little software engineers and reuse their code instead of reinventing the wheel.

The first thing we need to do is get access to ADMIN_MEDIA_PREFIX out of the settings so that we can include some of the admin javascript in our own interface, so we'll create a template context processor to handle that.

# context_processors.py
from django.conf import settings

def admin_media_prefix(request):
    return {'ADMIN_MEDIA_PREFIX': settings.ADMIN_MEDIA_PREFIX } 

Make sure to include this new template context processor in your settings in the TEMPLATE_CONTEXT_PROCESSORS tuple.

For information on writing your own context processors: here

Then we just include the admin interface's RelatedObjectLookups.js into our template:

<script src="{{ ADMIN_MEDIA_PREFIX }}js/admin/RelatedObjectLookups.js"></script>

Now we create a custom widget that calls the javascript we just included and attach it to the foreignkey fields:

#widgets.py
from django import forms
from django.template.loader import render_to_string

class SelectWithPopUp(forms.Select):
    model = None

    def __init__(self, model=None):
        self.model = model
        super(SelectWithPopUp, self).__init__()

    def render(self, name, *args, **kwargs):
        html = super(SelectWithPopUp, self).render(name, *args, **kwargs)

        if not self.model:
            self.model = name

        popupplus = render_to_string("formpopup.html", {'field': name, 'model': self.model})
        return html+popupplus

The template code for your widget:

<a href="/add/{{ model }}/" class="add-another" id="add_id_{{ field }}" onclick="return showAddAnotherPopup(this);">
+
</a>

Now you can attach your widget to any foreignkey select field on your form:

#forms.py
from app.widgets import SelectWithPopUp

class CustomForm(forms.Form):
    selectfield = forms.ModelChoiceField(Model.objects, widget=SelectWithPopUp)

The final piece of the puzzle is to create a view that can handle the saving and creation of the dynamic form:

# views.py
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect, HttpResponseNotFound, HttpResponse
from django.utils.html import escape
from django.forms.models import modelform_factory
from django.db.models.loading import get_models, get_app, get_apps

@login_required
def add_new_model(request, model_name):
    if (model_name.lower() == model_name):
        normal_model_name = model_name.capitalize()
    else:
        normal_model_name = model_name

    app_list = get_apps()
    for app in app_list:
        for model in get_models(app):
            if model.__name__ == normal_model_name:
                form = modelform_factory(model)

                if request.method == 'POST':
                    form = form(request.POST)
                    if form.is_valid():
                        try:
                            new_obj = form.save()
                        except forms.ValidationError, error:
                            new_obj = None

                        if new_obj:
                            return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \
                                (escape(new_obj._get_pk_val()), escape(new_obj)))

                else:
                    form = form()

                page_context = {'form': form, 'field': normal_model_name}
                return render_to_response('popup.html', page_context, context_instance=RequestContext(request))

The template code for your view:

<html>
<head>
<title>Add {{ field }}</title>
<script src="{{ ADMIN_MEDIA_PREFIX }}js/admin/RelatedObjectLookups.js"></script>
</head>
<body>
<h1>Add {{ field }}</h1>
<form method="POST" action="/add/{{ field }}">
        {% csrf_token %}
        <table>
        {{ form }}
        </table>
<p><input type="submit" /> | <a href="javascript:window.close()">Cancel</a></p>
</form>
</body>
</html>

I've implemented all this code into a re-usable django application that you can just drop into your own project here.

Thank you Mimsy for the original tips on how to implement this.