Я наконец-то смог решить проблему, используя подход, изложенный в этом посте, который добавляет ключи строки запроса к URL-адресу реферера, поскольку select2 не принимает изменение URL-адреса запроса после инициализации. Я также добавляю другую информацию о редактируемой собаке, такую как ее идентификатор и год рождения, для дальнейшей фильтрации набора запросов (собака не может быть собственным родителем или иметь родителя моложе себя, а матери могут быть только самками ...).
//this get passes to the select2:opening event listener
function expand_ajax_location_search($, fieldId) {
if (!$) {
$ = django.jQuery;
}
var pageURL = $(location).attr("href");
var match = pageURL.match(/\/.*\/(\d+)\/change/);
return `&birth_year=${$('#id_birth_year').val()}&dog_id=${match[1]}&father_cb=${$('#father-cb').prop( "checked" )}&mother_cb=${$('#mother-cb').prop( "checked" )}`
}
Наконец, фильтрация на стороне сервера была сложной задачей, потому что администратор собаки обычно фильтруется по питомнику, так что каждый владелец питомника может редактировать только своих собак, хотя флажок позволяет им использовать собак других питомников в качестве родители. Задача метода get_search_results состояла в том, чтобы отфильтровать набор запросов, когда флажок установлен, что невозможно сделать, поэтому создайте новый до , передав его в super (). Get_search_results. Также кажется, что базовый метод get_search_results пересекает все отношения, даже если они не нужны, что приводит к более чем 100 запросам, поэтому использование select_related для всех отношений приводит только к одному запросу.
def get_search_results(self, request, queryset, search_term):
if request.is_ajax and '/autocomplete/' in request.path and request.GET.get('model_name') == 'dog':
url = urllib.parse.urlparse(request.headers['Referer'])
referer = url.path
# (parse_qs results are lists)
qs = urllib.parse.parse_qs(url.query)
if request.GET.get('field_name') == 'father':
if qs.get('father_cb')[0] == 'true':
# default is filetered by kennel so need new qs
queryset = Dog.objects.select_related(
'kenn', 'img', 'father', 'mother', 'breeder').order_by('name')
queryset, use_distinct = super().get_search_results(request, queryset, search_term)
queryset = queryset.exclude(
sex='F').exclude(id=qs.get('dog_id')[0])
elif request.GET.get('field_name') == 'mother':
if qs.get('mother_cb')[0] == 'true':
# default is filetered by kennel so need new qs
queryset = Dog.objects.select_related(
'kenn', 'img', 'father', 'mother', 'breeder').order_by('name')
queryset, use_distinct = super().get_search_results(request, queryset, search_term)
queryset = queryset.exclude(
sex='M').exclude(id=qs.get('dog_id')[0])
birth_year = qs.get('birth_year')[0]
if birth_year:
queryset = queryset.exclude(birth_year__gt=birth_year)
else:
queryset, use_distinct = super().get_search_results(request, queryset, search_term)
return queryset, use_distinct