This is very similar to this question, but unfortunately, I still couldn't get it working.
I have a model, with a property that combines a few fields:
class Specimen(models.Model):
lab_number = ...
patient_name = ...
specimen_type = ...
@property
def specimen_name(self):
return f"{self.lab_number}_{self.patient_name}_{self.specimen_type}"
In Django Admin, when someone does a search, I can use the search_fields
attribute in the Model Admin to specify real fields, but not the specimen_name
custom field:
def specimen_name(inst):
return inst.specimen_name
specimen_name.short_description = "Specimen Name"
class SpecimenModelAdmin(admin.ModelAdmin):
list_display = ('specimen_name', 'patient_name', 'lab_number', 'specimen_type')
search_fields = ('patient_name', 'lab_number', 'specimen_type')
Doing a search using the code above, it will search the individual fields, but if I try to search for a full specimen_name in Django Admin, it won't find it, because none of the fields contain the exact, full specimen name.
The SO question I linked to above pointed me in the right direction - using get_search_results
. My code now looks something like this:
class SpecimenModelAdmin(admin.ModelAdmin):
...
search_fields = ('patient_name', 'lab_number', 'specimen_type')
def get_search_results(self, request, queryset, search_term):
if not search_term:
return queryset, False
queryset, may_have_duplicates = super().get_search_results(
request, queryset, search_term,
)
search_term_list = search_term.split(' ')
specimen_names = [q.specimen_name for q in queryset.all()]
results = []
for term in search_term_list:
for name in specimen_names:
if term in name:
results.append(name)
break
# Return original queryset, AND any new results we found by searching the specimen_name field
# The True indicates that it's possible that we will end up with duplicates
# I assume that means Django will make sure only unique results are returned when that's set
return queryset + results, True
As far as I know, I can't do a queryset.filter(specimen_name=SOMETHING)
. .filter
won't recognize the @property
method as a field in needs to search. That's why I write my own loop to do the searching.
The code above will obviously not work. You can't just add a list to a queryset. How would I return an actual queryset?