This is my model:
class Academic(models.Model):
SCHOOL_COLLEGE_SERVICE = [
('School Of Humanities', 'School Of Humanities'),
('School Of Culture & Creative Arts', 'School Of Culture & Creative Arts'),
('School Of Modern Languages & Cultures', 'School Of Modern Languages & Cultures'),
('School Of Critical Studies', 'School Of Critical Studies'),
('Arts College Of Arts Administration', 'Arts College Of Arts Administration'),
]
school = models.CharField(choices=SCHOOL_COLLEGE_SERVICE, max_length=50, blank=True, null=True)
I'd like to have a nice autocomplete / filter in my Django administration interface. Unfortunately it seems that it is not possible to have autocomplete if the dataset doesn't come from a ManyToMany or ForeignKey relationship. This is what I tried:
from django.contrib import admin
from .models import Academic, Partner, Project
from admin_auto_filters.filters import AutocompleteFilter
import django_filters
@admin.register(Academic)
class AcademicAdmin(admin.ModelAdmin):
search_fields = ['surname', 'forename']
#school = django_filters.ChoiceFilter(choices=Academic.SCHOOL_COLLEGE_SERVICE)
#autocomplete_fields = ['school']
I know I can also set a queryset like so:
class SchoolFilter(django_filters.FilterSet):
class Meta:
model = Academic
fields = ['school',]
But Django still complains that The value of 'autocomplete_fields[0]' must be a foreign key or a many-to-many field.
How can I achieve what I want?
if you don't want to rely on third party libraries, here is a simple widget that reuses Django's autocomplete media files (select2):
class AdminAutocompleteSelectWidget(forms.Select):
def __init__(self, choices=(), attrs=None):
super().__init__(attrs)
self.choices = choices
def render(self, name, value, attrs=None, renderer=None):
select_html = super().render(name, value, attrs, renderer)
select2_script = f"""
<script type="text/javascript">
(function($) {{
$(document).ready(function() {{
$('#id_{name}').select2();
}});
}})(django.jQuery);
</script>
"""
return select_html + select2_script
@property
def media(self):
# Reuse the AutocompleteMixin's media files
return AutocompleteMixin(None, None).media