Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save YellowSharkMT/46477c2e525d972c44dd7dc424ea8309 to your computer and use it in GitHub Desktop.
Save YellowSharkMT/46477c2e525d972c44dd7dc424ea8309 to your computer and use it in GitHub Desktop.
Customize Django's admin search results view to optionally show a column, with highlighted search term in the results.
"""
This is a fairly specific use-case, where we wanted to search columns on a related model, and present those results in a
sensible way. We wanted this column to only be present if the user is conducting a search, and we wanted to customize the
output to make the search term prominent in the results.
"""
import re
from django.contrib.admin import ModelAdmin
from django.utils import formats
from django.utils.safestring import mark_safe
class WriterAdmin(ModelAdmin):
# correspondencelog is a related model, notes is a field on that model.
search_fields = ('username', 'correspondencelog__notes')
list_display = ('id', 'username',)
# creates a dynamic function that can be used by the WriterAdmin to populate a column with request-specific content
def make_get_notes_function(self, query):
# this is used to wrap the search term in <b> tags...
search_exp = re.compile('(' + query + ')', re.IGNORECASE)
replace_exp = r'<b>\1</b>'
# this function will get attached to the WriterAdmin, as self.get_notes
def get_notes(obj):
matching_notes = obj.correspondencelog_set.filter(notes__contains='{}'.format(query))
# not a fan of this, would be cooler to use Django's template/context stuff...
notes_text = ''
notes_text_tpl = u'<span class="small date" title="{}">[{}]</span> {}<br/>'
for note in matching_notes:
short_date_string = formats.date_format(note.logged_at, 'SHORT_DATE_FORMAT')
long_date_string = formats.date_format(note.logged_at, 'DATETIME_FORMAT')
formatted_note = re.sub(search_exp, replace_exp, note.notes)
# gah, lots of .format(), sorry...
meta_text = u'By {} at {}'.format(note.logged_by.get_full_name(), long_date_string)
notes_text += notes_text_tpl.format(meta_text, short_date_string, formatted_note)
notes_text = notes_text[:-5] # trim off trailing '<br/>', yech...
return mark_safe(notes_text)
return get_notes
# This function is called early in the request process, and is our hook to update the ModelAdmin on-the-fly...
def changelist_view(self, request, extra_context=None):
# in this case, we want to customize the search results view...
if request.GET.get('q', None):
# update the self.list_display_value...
self.list_display = self.list_display + ('get_notes',)
# create the function that populates the column...
self.get_notes = self.make_get_notes_function(request.GET['q'])
self.get_notes.short_description = 'Notes'
return super(WriterAdmin, self).changelist_view(request, extra_context)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment