Created
March 28, 2013 13:56
-
-
Save ebrelsford/5263306 to your computer and use it in GitHub Desktop.
A modification of Django's admin widget RelatedFieldWidgetWrapper, which adds the handy + to select boxes when picking a related model. This one doesn't assume the user's picking a related model instance--it simply lets the user pick a model instance or add a new one if needed. This is useful on forms (such as the example in forms.py) where you …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
An example form using AddAnotherWidgetWrapper. | |
""" | |
from django import forms | |
from .models import Owner | |
from .widgets import AddAnotherWidgetWrapper | |
class PickOwnerForm(forms.Form): | |
owner = forms.ModelChoiceField( | |
queryset=Owner.objects.all().order_by('name'), | |
widget=AddAnotherWidgetWrapper( | |
forms.Select(), | |
Owner, | |
) | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% extends "admin/base_site.html" %} | |
{% comment %} | |
An example template that renders a form where an AddAnotherWidgetWrapper is present. | |
{% endcomment %} | |
{% load i18n admin_static admin_modify %} | |
{% load admin_urls %} | |
{% block extrahead %} | |
{{ block.super }} | |
<script src="{{ STATIC_URL }}admin/js/admin/RelatedObjectLookups.js"></script> | |
{% block bodyclass %}change-list{% endblock %} | |
{% block content %} | |
<div> | |
Pick an owner or add a new one: | |
</div> | |
{{ form.media }} | |
<form method="post"> | |
{% csrf_token %} | |
{{ form.as_p }} | |
<input type="submit" value="{% trans "Picked" %}" /> | |
</form> | |
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import copy | |
from django import forms | |
from django.contrib.admin.templatetags.admin_static import static | |
from django.core.urlresolvers import reverse | |
from django.utils.safestring import mark_safe | |
from django.utils.translation import ugettext as _ | |
class AddAnotherWidgetWrapper(forms.Widget): | |
""" | |
This class is a wrapper to a given widget to add the add icon for the | |
admin interface. Modeled after | |
django.contrib.admin.widgets.RelatedFieldWidgetWrapper | |
""" | |
def __init__(self, widget, model): | |
self.is_hidden = widget.is_hidden | |
self.needs_multipart_form = widget.needs_multipart_form | |
self.attrs = widget.attrs | |
self.choices = widget.choices | |
self.widget = widget | |
self.model = model | |
def __deepcopy__(self, memo): | |
obj = copy.copy(self) | |
obj.widget = copy.deepcopy(self.widget, memo) | |
obj.attrs = self.widget.attrs | |
memo[id(self)] = obj | |
return obj | |
@property | |
def media(self): | |
return self.widget.media | |
def render(self, name, value, *args, **kwargs): | |
model = self.model | |
info = (model._meta.app_label, model._meta.object_name.lower()) | |
self.widget.choices = self.choices | |
output = [self.widget.render(name, value, *args, **kwargs)] | |
related_url = reverse('admin:%s_%s_add' % info) | |
output.append(('<a href="%s" class="add-another" id="add_id_%s" ' + | |
'onclick="return showAddAnotherPopup(this);"> ') | |
% (related_url, name)) | |
output.append('<img src="%s" width="10" height="10" alt="%s"/></a>' | |
% (static('admin/img/icon_addlink.gif'), | |
_('Add Another'))) | |
return mark_safe(''.join(output)) | |
def build_attrs(self, extra_attrs=None, **kwargs): | |
"Helper function for building an attribute dictionary." | |
self.attrs = self.widget.build_attrs(extra_attrs=None, **kwargs) | |
return self.attrs | |
def value_from_datadict(self, data, files, name): | |
return self.widget.value_from_datadict(data, files, name) | |
def _has_changed(self, initial, data): | |
return self.widget._has_changed(initial, data) | |
def id_for_label(self, id_): | |
return self.widget.id_for_label(id_) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, I want to use ForeignKeyRawIdWidget with my custom model, due to pop-up window.
We are still using LTS django 1.4 and nothing but the plain input is displayed. There is no icon for selecting the choice that I want.
Have you got any suggestions?