Admin Integration¶
Overview¶
Django-Selectables will work in the admin. To get started on integrated the fields and widgets in the admin make sure you are familiar with the Django documentation on the ModelAdmin.form and ModelForms particularly on overriding the default widgets. As you will see integrating django-selectable in the adminis the same as working with regular forms.
Including jQuery & jQuery UI¶
As noted in the quick start guide, the jQuery and jQuery UI libraries are not included in the distribution but must be included in your templates. For the Django admin that means overriding admin/base_site.html. You can include this media in the block name extrahead which is defined in admin/base.html.
{% block extrahead %} {% load selectable_tags %} {% include_ui_theme %} {% include_jquery_libs %} {% endblock %}
See the Django documentation on overriding admin templates. See the example project for the full template example.
Using Grappelli¶
New in version 0.7.
Grappelli is a popular customization of the Django
admin interface. It includes a number of interface improvements which are also built on top of
jQuery UI. When using Grappelli you do not need to make any changes to the admin/base_site.html
template. django-selectable will detect jQuery and jQuery UI versions included by Grappelli
and make use of them.
Basic Example¶
In our sample project we have a Farm
model with a foreign key to auth.User
and
a many to many relation to our Fruit
model.
class Farm(models.Model): name = models.CharField(max_length=200) owner = models.ForeignKey('auth.User', related_name='farms') fruit = models.ManyToManyField(Fruit) def __unicode__(self): return "%s's Farm: %s" % (self.owner.username, self.name)
In admin.py we will define the form and associate it with the FarmAdmin.
class FarmAdminForm(forms.ModelForm): owner = selectable.AutoCompleteSelectField(lookup_class=OwnerLookup, allow_new=True) class Meta(object): model = Farm widgets = { 'fruit': selectable.AutoCompleteSelectMultipleWidget(lookup_class=FruitLookup), } exclude = ('owner', ) def __init__(self, *args, **kwargs): super(FarmAdminForm, self).__init__(*args, **kwargs) if self.instance and self.instance.pk and self.instance.owner: self.initial['owner'] = self.instance.owner.pk def save(self, *args, **kwargs): owner = self.cleaned_data['owner'] if owner and not owner.pk: owner = User.objects.create_user(username=owner.username, email='') self.instance.owner = owner return super(FarmAdminForm, self).save(*args, **kwargs)class FarmAdmin(admin.ModelAdmin): form = FarmAdminForm
You’ll note this form also allows new users to be created and associated with the
farm, if no user is found matching the given name. To make use of this feature we
need to add owner
to the exclude so that it will pass model validation. Unfortunately
that means we must set the owner manual in the save and in the initial data because
the ModelForm
will no longer do this for you. Since fruit
does not allow new
items you’ll see these steps are not necessary.
The django-selectable widgets are compatitible with the add another popup in the
admin. It’s that little green plus sign that appears next to ForeignKey
or
ManyToManyField
items. This makes django-selectable a user friendly replacement
for the ModelAdmin.raw_id_fields
when the default select box grows too long.
Inline Example¶
With our Farm
model we can also associate the UserAdmin
with a Farm
by making use of the InlineModelAdmin.
We can even make use of the same FarmAdminForm
.
class FarmInline(admin.TabularInline): model = Farm form = FarmAdminFormclass NewUserAdmin(UserAdmin): inlines = [ FarmInline, ]
The auto-complete functions will be bound as new forms are added dynamically.