我有一個選擇字段,當更改爲另一個值時,它必須更改表單中的其他字段。當瀏覽器中的值發生變化時,如何刷新django admin窗體?
所以我需要刷新窗體,或者用ajax調用來更新字段。這是可能的管理表單?
我有一個選擇字段,當更改爲另一個值時,它必須更改表單中的其他字段。當瀏覽器中的值發生變化時,如何刷新django admin窗體?
所以我需要刷新窗體,或者用ajax調用來更新字段。這是可能的管理表單?
它絕對有可能在django admin中使用javascript的動態字段。
舉一個很好的例子,我建議django-smart-selects
和django-admin-flexselect
。
碰到這個問題就來了一段時間回來。以下是我最終解決它,能過濾Buildings
下來Floors
到Rooms
一個例子(Django的2.0.3):
#admin.py
class BuildingAdmin(admin.ModelAdmin):
class Media:
js = ("jquery-3.3.1.min.js","buildingfilter.js")
# Your other admin options for fields, filters, etc.
# The script will use the id's of the fields you included
# If the filters you want aren't actually FK's in the model,
# just use a ModelForm to add extra fields and use those
# element id's in the script.
#views.py
def building(request):
if request.method == 'GET' and request.is_ajax():
building_id = request.GET.get('id')
json_floor = serializers.serialize("json", Floor.objects.filter(fkbuilding_id=building_id))
return HttpResponse(json_floor, content_type='application/json')
else:
return HttpResponse("no-go")
def addequip_floor(request):
if request.method == 'GET' and request.is_ajax():
floor_id = request.GET.get('id')
json_location = serializers.serialize("json", Location.objects.filter(fkfloor_id=floor_id))
return HttpResponse(json_location, content_type='application/json')
else:
return HttpResponse("no-go")
#urls.py
urlpatterns = [
...
path('building/', views.building),
path('floor/', views.floor),
]
#buildingfilter.js
$(function(){
//Boilerplate AJAX loading if using cookies
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
console.log("Cookies loaded");
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
console.log("CRSF Safe");
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
//Code that does the filtering
$("#id_building").on('change', function(e) {
e.preventDefault();
console.log($(this).val());
$.getJSON("http://127.0.0.1:8000/building/",{id: $(this).val()}, function(j) {
var options = '<option value="">---??---</option>';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + parseInt(j[i].pk) + '">' + j[i].fields['name'] + '</option>';
}
console.log(options);
$("#id_floor").html(options);
$("#id_floor option:first").attr('selected', 'selected');
});
$("#id_building").attr('selected', 'selected');
});
$("#id_floor").on('change', function(e) {
e.preventDefault();
console.log($(this).val());
$.getJSON("http://127.0.0.1:8000/floor/",{id: $(this).val()}, function(j) {
var options = '<option value="">---??---</option>';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + parseInt(j[i].pk) + '">' + j[i].fields['name'] + '</option>';
}
console.log(options);
$("#id_room").html(options);
$("#id_room option:first").attr('selected', 'selected');
});
$("#id_floor").attr('selected', 'selected');
});
});