Features: 1) Add data-lookup-kwarg to autocomplete input for better filtering; 2) Streamline admin autocomplete URL structure for consistency;
Fixes: 1) Replace outdated jQuery UI paths with modern equivalents; 2) Ensure proper retrieval of JSON responses in autocomplete widget; 3) Correct misaligned parameter initialization in `AdminFilter`; Extra: Minor formatting improvements and variable renaming for readability.
This commit is contained in:
parent
90c8f87502
commit
83ac6b27e6
2 changed files with 37 additions and 38 deletions
|
|
@ -42,20 +42,17 @@ class RelatedAutocompleteFilter(FieldListFilter):
|
||||||
limit = 10
|
limit = 10
|
||||||
|
|
||||||
def __init__(self, field, request, params, model, model_admin, field_path):
|
def __init__(self, field, request, params, model, model_admin, field_path):
|
||||||
self.field = field
|
|
||||||
self.request = request
|
|
||||||
self.params = params
|
|
||||||
self.model_admin = model_admin
|
|
||||||
self.field_path = field_path
|
|
||||||
|
|
||||||
self.lookup_kwarg = f"{field_path}__{field.target_field.name}__exact"
|
self.lookup_kwarg = f"{field_path}__{field.target_field.name}__exact"
|
||||||
self.lookup_val = params.get(self.lookup_kwarg, "")
|
self.lookup_val = params.get(self.lookup_kwarg, "")
|
||||||
|
|
||||||
opts = model_admin.model._meta
|
remote = field.remote_field.model._meta
|
||||||
url_name = f"admin:{opts.app_label}_{opts.model_name}_autocomplete"
|
base_url = reverse("admin:autocomplete")
|
||||||
self.autocomplete_url = (
|
self.autocomplete_url = (
|
||||||
reverse(url_name)
|
f"{base_url}"
|
||||||
+ f"?field_name={field_path}&limit={self.limit}"
|
f"?app_label={remote.app_label}"
|
||||||
|
f"&model_name={remote.model_name}"
|
||||||
|
f"&field_name={field.name}"
|
||||||
|
f"&limit={self.limit}"
|
||||||
)
|
)
|
||||||
|
|
||||||
def expected_parameters(self):
|
def expected_parameters(self):
|
||||||
|
|
@ -66,15 +63,15 @@ class RelatedAutocompleteFilter(FieldListFilter):
|
||||||
|
|
||||||
def choices(self, changelist):
|
def choices(self, changelist):
|
||||||
yield {
|
yield {
|
||||||
"selected": bool(self.lookup_val),
|
"selected": bool(self.lookup_val),
|
||||||
"query_string": changelist.get_query_string(
|
"query_string": changelist.get_query_string(
|
||||||
{self.lookup_kwarg: self.lookup_val} if self.lookup_val else {},
|
({self.lookup_kwarg: self.lookup_val} if self.lookup_val else {}),
|
||||||
[]
|
[]
|
||||||
),
|
),
|
||||||
"display": _("—"),
|
"display": _("—"),
|
||||||
"autocomplete_url": self.autocomplete_url,
|
"autocomplete_url": self.autocomplete_url,
|
||||||
"lookup_kwarg": self.lookup_kwarg,
|
"lookup_kwarg": self.lookup_kwarg,
|
||||||
"lookup_val": self.lookup_val,
|
"lookup_val": self.lookup_val,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,43 @@
|
||||||
{% load i18n admin_urls static %}
|
{% load i18n static %}
|
||||||
<div class="filter-autocomplete">
|
<div class="filter-autocomplete">
|
||||||
{# A hidden input to carry the selected value #}
|
<input type="hidden"
|
||||||
<input type="hidden" name="{{ spec.lookup_kwarg }}" value="{{ spec.lookup_val }}" id="id_{{ spec.lookup_kwarg }}"/>
|
name="{{ spec.lookup_kwarg }}"
|
||||||
{# The visible text input #}
|
value="{{ spec.lookup_val }}"
|
||||||
|
id="id_{{ spec.lookup_kwarg }}"/>
|
||||||
|
|
||||||
<label for="id_autocomplete_{{ spec.lookup_kwarg }}"></label><input type="text"
|
<label for="id_autocomplete_{{ spec.lookup_kwarg }}"></label><input type="text"
|
||||||
placeholder="{% trans 'Search…' %}"
|
|
||||||
id="id_autocomplete_{{ spec.lookup_kwarg }}"
|
id="id_autocomplete_{{ spec.lookup_kwarg }}"
|
||||||
style="width: 90%;"
|
placeholder="{% trans 'Search…' %}"
|
||||||
|
style="width:90%;"
|
||||||
data-autocomplete-url="{{ spec.autocomplete_url }}"
|
data-autocomplete-url="{{ spec.autocomplete_url }}"
|
||||||
value="{% if spec.lookup_val %}{{ spec.lookup_val|get_obj_display:spec.field_path }}{% endif %}"
|
data-lookup-kwarg="{{ spec.lookup_kwarg }}"/>
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="{% static 'admin/js/jquery.init.js' %}"></script>
|
<script src="{% static 'admin/js/jquery.init.js' %}"></script>
|
||||||
<script src="{% static 'admin/js/jquery.ui.core.js' %}"></script>
|
<script src="{% static 'admin/js/vendor/jquery/jquery.js' %}"></script>
|
||||||
<script src="{% static 'admin/js/jquery.ui.autocomplete.js' %}"></script>
|
<script src="{% static 'admin/js/vendor/jquery/jquery.ui.js' %}"></script>
|
||||||
<link rel="stylesheet" href="{% static 'admin/css/jquery-ui.css' %}"/>
|
<link rel="stylesheet"
|
||||||
|
href="{% static 'admin/css/vendor/jquery-ui/jquery-ui.min.css' %}"/>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
(function ($) {
|
(function ($) {
|
||||||
let $input = $('#id_autocomplete_{{ spec.lookup_kwarg }}');
|
let $box = $('#id_autocomplete_{{ spec.lookup_kwarg }}');
|
||||||
let $hidden = $('#id_{{ spec.lookup_kwarg }}');
|
let $hidden = $('#id_{{ spec.lookup_kwarg }}');
|
||||||
|
|
||||||
$input.autocomplete({
|
$box.autocomplete({
|
||||||
source: function (request, response) {
|
source: function (req, resp) {
|
||||||
$.getJSON($input.data('autocomplete-url'), {
|
$.getJSON($box.data('autocomplete-url'), {
|
||||||
term: request.term // admin autocomplete expects "term"
|
term: req.term
|
||||||
}, response);
|
}, function (data) {
|
||||||
|
resp(data.results);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
minLength: 2,
|
minLength: 2,
|
||||||
select: function (event, ui) {
|
select: function (_, ui) {
|
||||||
// ui.item.id and ui.item.text come from the JSON returned
|
|
||||||
$hidden.val(ui.item.id);
|
$hidden.val(ui.item.id);
|
||||||
// trigger a reload of the changelist with the new filter
|
let qs = {};
|
||||||
let params = {};
|
qs[$box.data('lookup-kwarg')] = ui.item.id;
|
||||||
params["{{ spec.lookup_kwarg }}"] = ui.item.id;
|
window.location.search = $.param(qs);
|
||||||
window.location.search = $.param(params);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})(django.jQuery);
|
})(django.jQuery);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue