the issue I'm facing is I set a district and the city which is under the district and save it. It saves correctly to the database. And when I come back to the page and change the city and save, the city is set to null and the district too is set to null in the database How do I solve it Context: Trying to overwrite Django-admin change_form for SchoolProfileForm and for the dependable dropdown of the province, district, city, and ward. when trying to change the already saved city from before, the district value is reset to nothing, and also the city's value(the same issue with the ward, the city is also reset)
Javascript Functions:
function resetDistrict() {
let $ = django.jQuery;
let district_list = '<option value="" selected="">---------</option>'
$('#select2-id_district-container').html(district_list);
console.log(district_list)
}
function getDistrict(province_id) {
resetDistrict()
let $ = django.jQuery;
$.get('/school/district/' + province_id, function (resp){
let district_list = '<option value="" selected="">---------</option>'
$.each(resp.data, function(i, item){
district_list += '<option value="'+ item.id +'">'+ item.name +'</option>'
});
$('#id_district').html(district_list);
});
}
function getDistrictfromDb(province_id) {
let $ = django.jQuery;
$.get('/school/district/' + province_id, function (resp){
let district_list = '<option value="" selected="">---------</option>'
$.each(resp.data, function(i, item){
district_list += '<option value="'+ item.id +'">'+ item.name +'</option>'
});
$('#id_district').html(district_list);
});
}
function resetCity() {
let $ = django.jQuery;
let city_list = '<option value="" selected="">---------</option>'
$('#select2-id_city-container').html(city_list);
console.log(city_list)
}
function getCity(district_id) {
resetCity();
let $ = django.jQuery;
$.get('/school/city/' + district_id, function (resp){
let city_list = '<option value="" selected="">---------</option>'
$.each(resp.data, function(i, item){
city_list += '<option value="'+ item.id +'">'+ item.name +'</option>'
});
$('#id_city').html(city_list);
});
}
function getCityfromDb(district_id) {
let $ = django.jQuery;
$.get('/school/city/' + district_id, function (resp){
let city_list = '<option value="" selected="">---------</option>'
$.each(resp.data, function(i, item){
city_list += '<option value="'+ item.id +'">'+ item.name +'</option>'
});
$('#id_city').html(city_list);
});
}
function resetWard() {
let $ = django.jQuery;
let ward_list = '<option value="" selected="">---------</option>'
$('#select2-id_ward-container').html(ward_list);
console.log(ward_list)
}
function getWard(city_id) {
resetWard()
let $ = django.jQuery;
$.get('/school/ward/' + city_id, function (resp){
let ward_list = '<option value="" selected="">---------</option>'
$.each(resp.data, function(i, item){
ward_list += '<option value="'+ item.id +'">'+ item.name +'</option>'
});
$('#id_ward').html(ward_list);
});
}
function getWardfromDb(city_id) {
let $ = django.jQuery;
$.get('/school/ward/' + city_id, function (resp){
let ward_list = '<option value="" selected="">---------</option>'
$.each(resp.data, function(i, item){
ward_list += '<option value="'+ item.id +'">'+ item.name +'</option>'
});
$('#id_ward').html(ward_list);
});
}
and the forms.py to overwrite django admin form:
class SchoolProfileForm(forms.ModelForm):
class Meta:
model = SchoolProfile
fields = '__all__'
def __init__(self, *args, **kwargs):
super(SchoolProfileForm, self).__init__(*args, **kwargs)
# when there is instance key, select the default value
# Province always loaded for initial data,
# because Province is on the first level
try:
self.initial['province'] = kwargs['instance'].province.id
except:
pass
province_list = [('', '---------')] + [(i.id, i.name) for i in Province.objects.all()]
# District, City, and Ward are on the child level,
# it will be loaded when user click the parent level
try:
self.initial['district'] = kwargs['instance'].district.id
district_init_form = [(i.id, i.name) for i in District.objects.filter(
province=kwargs['instance'].province
)]
except:
district_init_form = [('', '---------')]
try:
self.initial['city'] = kwargs['instance'].city.id
city_init_form = [(i.id, i.name) for i in City.objects.filter(
district=kwargs['instance'].district
)]
except:
city_init_form = [('', '---------')]
try:
self.initial['ward'] = kwargs['instance'].ward.id
ward_init_form = [(i.id, i.name) for i in Ward.objects.filter(
city=kwargs['instance'].city
)]
except:
ward_init_form = [('', '---------')]
# Overriding the form, adding onchange attribute to call the ajax function
self.fields['province'].widget = forms.Select(
attrs={
'id': 'id_province',
'class': 'location-select',
'onchange': 'getDistrict(this.value);',
},
choices=province_list,
)
self.fields['district'].widget = forms.Select(
attrs={
'id': 'id_district',
'class': 'location-select',
'onchange': 'getCity(this.value);',
},
choices=district_init_form
)
self.fields['city'].widget = forms.Select(
attrs={
'id': 'id_city',
'class': 'location-select',
'onchange': 'getWard(this.value);',
},
choices=city_init_form
)
self.fields['ward'].widget = forms.Select(
attrs={
'id': 'id_ward',
'class': 'location-select',
},
choices=ward_init_form
)
self.fields['locale'].widget = forms.TextInput(
attrs={
'id': 'id_locale',
'width': '200px',
},
)
views.py
def province_list(request):
province = Province.objects.all()
return JsonResponse({'data':[{'id': p.id, 'name': p.name} for p in province ]})
def district_list(request, province_id):
district = District.objects.filter(province_id=province_id)
return JsonResponse({'data': [{'id': d.id, 'name': d.name} for d in district ]})
def city_list(request, district_id):
city = City.objects.filter(district_id=district_id)
return JsonResponse({'data': [{'id': c.id, 'name': c.name} for c in city]})
def ward_list(request, city_id):
ward = Ward.objects.filter(city_id=city_id)
return JsonResponse({'data': [{'id': w.id, 'name': w.name} for w in ward ]})
from Django Chained Dropdown implementation on Django admin
No comments:
Post a Comment