开发系统: windows
IDE: pycharm
数据库: msyql,navicat
编程语言: python3.7 (Windows x86-64 executable installer)
虚拟环境: virtualenvwrapper
开发框架: Django 2.2
Django 2.2通病===>访问admin出现问题:
报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6 in position 9737: illegal multibyte sequence
二 Django Admin 实现三级联动的示例代码(省市区)===>小白级
1. 在 model.py 中
from django.db importmodels#人员
classMember(models.Model):
name= models.CharField(max_length=100, verbose_name='姓名')
province= models.ForeignKey('Province', on_delete=models.PROTECT, null=True, blank=True, verbose_name='省份')
city= models.ForeignKey('City', on_delete=models.PROTECT, null=True, blank=True, verbose_name='城市')
district= models.ForeignKey('District', on_delete=models.PROTECT, null=True, blank=True, verbose_name='区/县')classMeta:
verbose_name_plural= verbose_name = '00-人员'
def __str__(self):returnself.name#省份
classProvince(models.Model):
省份= models.CharField(max_length=100, null=True, blank=True, verbose_name='省份')classMeta:
verbose_name_plural= verbose_name = '01-省份'
def __str__(self):returnself.省份#城市
classCity(models.Model):
城市= models.CharField(max_length=100, null=True, blank=True, verbose_name='城市')
省份= models.ForeignKey('Province', on_delete=models.PROTECT, null=True, blank=True, related_name='城市_省份',
verbose_name='省份')classMeta:
verbose_name_plural= verbose_name = '02-城市'
def __str__(self):returnself.城市#区/县
classDistrict(models.Model):
区县= models.CharField(max_length=100, null=True, blank=True, verbose_name='区/县')
城市= models.ForeignKey('City', on_delete=models.PROTECT, null=True, blank=True, related_name='区县_城市',
verbose_name='城市')classMeta:
verbose_name_plural= verbose_name = '03-区/县'
def __str__(self):return self.区县
2. 在 view.py 中
from django.http importJsonResponsefrom sjld.models importProvince, City, District#Create your views here.
#省份
defchoose_province(request):
省份=Province.objects.all()
result=[]for i in省份:
result.append(i.省份)#取公司的简称
province = result #传递一个列表
return JsonResponse(province, safe=False)defchoose_city(request):
省份= request.GET.get('p') #取上面选中省份的名称
城市 =City.objects.all()
result=[]for i in城市:if str(省份) ==str(i.省份):
result.append(i.城市)
cities= result #传递一个列表
return JsonResponse(cities, safe=False)defchoose_district(request):
城市= request.GET.get('c') #取上面选中城市的名称
区县 =District.objects.all()
result=[]for i in区县:if str(城市) ==str(i.城市):
result.append(i.区县)
cities= result #传递一个列表
districts =citiesreturn JsonResponse(districts, safe=False)
3. 在 urls.py 中
from django.contrib importadminfrom django.urls importpathfrom sjld.views importchoose_province, choose_city, choose_district
urlpatterns=[
path('admin/', admin.site.urls),
path('province/', choose_province),
path('city/', choose_city),
path('district/', choose_district),
]
4. 在 admin.py 中
from django importformsfrom django.contrib importadminfrom shanjld.models importMember, Province, City, DistrictclassMemberForm(forms.ModelForm):classMeta:
widgets={'province': forms.Select(),'city': forms.Select(),'district': forms.Select()
}#人员
@admin.register(Member)classMemberAdmin(admin.ModelAdmin):
form=MemberForm
change_form_template= 'area.html'
#raw_id_fields = ('province', 'city', 'district',) # 这个在这里就无效了,希望哪位大老指点一下,怎么重写这个方法.
fields = ('name', 'province', 'city', 'district')
list_display= ('name', 'province', 'city', 'district')#省份
@admin.register(Province)classProvinceAdmin(admin.ModelAdmin):pass
#城市
@admin.register(City)classCityAdmin(admin.ModelAdmin):
raw_id_fields= ('省份',)#区/县
@admin.register(District)classDistrictAdmin(admin.ModelAdmin):
raw_id_fields= ('城市',)
5. 在项目 templates 文件下新建一个 area.html 文件
6. 找到django源码中的 change_form.html 文件,打开复制里面全部的html内容到 area.html 中. (文件在 External Libraries => python3.7(我用的这个版本) => site-packages => django/contrib/admin/templates/admin/).
7. 在 area.html 文件中找到 {% block admin_change_form_document_ready %} (在66行) , 用下面代码覆盖全部 {% block admin_change_form_document_ready %} .
7.1 area.html 中所有增加替换代码
{% block admin_change_form_document_ready %}
$('#id_city').change(function() {
let p_id= $('#id_province').val();
let c_id= $('#id_city').val();
$.get('/district/', {"p": p_id, "c": c_id }, function(a_info) {
var area_info= $('#id_district').empty().append('' + '---------' + '');
$.each(a_info, function(i, area) {
area_info.append('' + area + '')
});
{% if change %}
$("#id_district").find("option:contains({{ original.district }})").attr('selected', true);
{% endif %}
});
});
$('#id_province').change(function() {
let p_id= $('#id_province').val();
$.get('/city/', { 'p': p_id }, function(c_info) {
var city_info= $('#id_city').empty().append('' + '---------' + '');
$.each(c_info, function(i, city) {
city_info.append('' + city + '')
});
{% if change %}
$("#id_city").find("option:contains({{ original.city }})").attr('selected', true);
$("#id_city").trigger("change");
{% endif %}
});
});
$.get('/province/', function(p_info) {
var province_info= $('#id_province').empty().append('' + '---------' + '');
$.each(p_info, function(i, province) {
province_info.append('' + province + '')
});
{% if change %}
$("#id_province").find("option:contains({{ original.province }})").attr('selected', true);
$("#id_province").trigger("change");
{% endif %}
});
})(django.jQuery);{% endblock %}
7.2 area.html 中所有代码
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block extrahead %}{{ block.super }}{{ media }}
{% endblock %}
{% block extrastyle %}{{ block.super }}{% endblock %}
{% block coltype %}colM{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
{% endblock %}{% endif %}
{% block content %}
{% if change %}{% if not is_popup %}
- {% block object-tools-items %}
{% change_form_object_tools %}
{% endblock %}
{% endif %}{% endif %}{% endblock %}
{% csrf_token %}{% block form_top %}{% endblock %}{% if to_field %}{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if errors %}
{% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
{{ adminform.form.non_field_errors }}{% endif %}
{% block field_sets %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}
{% block after_field_sets %}{% endblock %}
{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}
{% block after_related_objects %}{% endblock %}
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
{% block admin_change_form_document_ready %}
{% endblock %}
{#JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
8.效果
9.访问admin出现问题:
报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6 in position 9737: illegal multibyte sequence
10.请各位大老多多指点! ===> 个人微信:DJtang009