1.静态文件
项目中的CSS、图片、js都是静态文件。一般会将静态文件放到一个单独的目录中,以方便管理。在html页面中调用时,也需要指定静态文件的路径,
Django中提供了一种解析的方式配置静态文件路径。静态文件可以放在项目根目录下,也可以放在应用的目录下,由于有些静态文件在项目中是通用的,
所以推荐放在项目的根目录下,方便管理。
1.1 使用
(1) 新建 "static" 文件
(2) 配置静态文件的物理路径
引入静态文件
1.2 加载目录
STATICFILES_FINDERS=(
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder'
)
1、首先读取 STATICFILES_DIRS 中的静态文件
2、没有的话,就到每个应用中查找有没有 static 文件
2.中间件
Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。
中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性,其它的MVC框架也有这个功能,名称为IoC。
(1) 如果在某个函数显式返回,则它会跳过后续函数,直接到达 process_response
Django在中间件中预置了五个方法,这五个方法的区别在于不同的阶段执行,对输入或输出进行干预,方法如下:
1)处理请求前:在每个请求上,request对象产生之后,url匹配之前调用,返回None或HttpResponse对象。
def process_request(self, request): pass
2)处理视图前:在每个请求上,url匹配之后,视图函数调用之前调用,返回None或HttpResponse对象。
def process_view(self, request, view_func, *view_args, **view_kwargs): pass
(3) 只有当response实例拥有 ``render()`` 方法时 ``process_template_response()`` 才会调用
def process_template_response(self,request,response):
pass
4)处理响应后:视图函数调用之后,所有响应返回浏览器之前被调用,在每个请求上调用,返回HttpResponse对象。
def process_response(self, request, response):
pass
5)异常处理:当视图抛出异常时调用,在每个请求上调用,返回一个HttpResponse对象。
def process_exception(self, request,exception): pass
2.1 使用中间件
(1) 新建middleware.py文件
(2) 定义中间件类。
注意:
如果多个注册的中间件类中都有process_exception的方法,则先注册的后执行
(3) 注册中间件类
3.上传图片
3.1 配置上传文件保存目录
1 新建上传文件保存目录
2 配置上传文件保存目录
3.2 后台管理页面上传图片
1) 设计模型类。
2) 迁移生成表格
3 注册模型类
# admin 里上传图片
admin.site.register(PicTest)
3.3 用户自定义页面上传图片
1) 定义用户上传图片的页面并显示,是一个自定义的表单。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传图片</title>
</head>
<body>
<form action="/upload_handle/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="pic"> <br>
<input type="submit" value="上传">
</form>
</body>
</html>
2 定义接收上传文件的视图函数。
request对象有一个FILES的属性,类似于字典,通过request.FILES可以获取上传文件的处理对象
def upload_handle(request):
'''上传图片处理'''
# 1.获取上传文件的处理对象
pic = request.FILES['pic']
# 2.创建一个文件
save_path = '%s/booktest/%s' % (settings.MEDIA_ROOT, pic.name)
with open(save_path, 'wb') as f:
# 3.获取上传文件的内容写到创建的文件中
for content in pic.chunks(): # pic.chunks() 是生成器返回的文件块
f.write(content)
# 4. 在数据库保存
PicTest.objects.create(goods_pic='booktest/%s' % pic.name)
return HttpResponse('ok')
在django中,上传文件不大于2.5M,文件放在内存中。上传文件大于2.5M,文件内容写到一个临时文件中。
Django处理上传文件的两个类:
FILE_UPLOAD_HANDLERS= (
"django.core.files.uploadhandler.MemoryFileUploadHandler",
"django.core.files.uploadhandler.TemporaryFileUploadHandler"
)
4 . 分页
Django提供了数据分页的类,这些类被定义在django / core / paginator.py中。类Paginator用于对列进行一页n条数据的分页运算。类页用于表示第m页的数据。
Paginator类实例对象
- 方法_init_(列表,int):返回分页对象,第一个参数为列表数据,第二个参数为每页数据的条数。
- 属性count:返回对象总数。
- 属性num_pages:返回页面总数。
- 属性page_range:返回页码列表,从1开始,例如[1, 2, 3, 4]。
- 方法page(m):返回Page类实例对象,表示第m页的数据,下标以1开始。
Page类实例对象
- 调用Paginator对象的page()方法返回Page对象,不需要手动构造。
- 属性object_list:返回当前页对象的列表。
- 属性number:返回当前是第几页,从1开始。
- 属性paginator:当前页对应的Paginator对象。
- 方法has_next():如果有下一页返回True。
- 方法has_previous():如果有上一页返回True。
- 方法len():返回当前页面对象的个数

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>分页</title> </head> <body> <ul> {% for area in page %} <li>{{ area.atitle }}</li> {% endfor %} </ul> {% if page.has_previous %} <a href="/show_area{{ page.previous_page_number }}"><上一页</a> {% endif %} {% for pindex in page.paginator.page_range %} {% if pindex == page.number %} {{ pindex }} {% else %} <a href="/show_area{{ pindex }}/">{{ pindex }}</a> {% endif %} {% endfor %} {% if page.has_next %} <a href="/show_area{{ page.next_page_number }}">>下一页</a> {% endif %} </body> </html>

def show_area(request, pindex): '''分页''' # 1 查询出所有省级地区信息 areas = AreaInfo.objects.filter(aParent__isnull=True) # 2 分页 paginator = Paginator(areas, 10) # 3 获取第pindex的内容 if pindex == "": pindex = 1 else: pindex = int(pindex) page = paginator.page(pindex) return render(request, 'booktest/show_area.html', {'page': page})
5.案例

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>省市县选择案例</title> </head> <body> <select name="" id="prov"> <option value="">----请选择省----</option> </select> <select name="" id="city"> <option value="">----请选择市----</option> </select> <select name="" id="dis"> <option value="">----请选择县----</option> </select> <script src="/static/js/jquery-1.12.4.min.js"></script> <script> // 1 发起AJAX请求,获得所有省级地区的信息 $.get('/prov', function (data) { // 回调函数 res = data.data; // 获取返回的json数据 prov = $('#prov'); // 遍历res数组,获取每个元素 [地址id,地区标题] $.each(res, function (index, item) { id = item[0]; atitle = item[1]; option_str = '<option value="' + id + '">' + atitle + '</option>'; prov.append(option_str) }) /* for(i=0;i<res.length;i++){ id =res[i][0]; atitle = res[i][1]; option_str = '<option value="'+ id +'">'+atitle+'</option>'; // 向下拉框追加元素 prov.append(option_str) } */ }); // 2 绑定prov下拉列表框的change事件 $('#prov').change(function () { // 发起AJAX请求,获得所有省下面市级的信息$ // 获取点击省的id prov_id = $(this).val(); $.get('/city' + prov_id, function (data) { res = data.data; // 获取返回的json数据 city = $('#city'); // 清空 city.empty().append( '<option value="">----请选择市----</option>' ); dis = $('#dis'); // 清空 下拉列表 dis.empty().append( '<option value="">----请选择县----</option>' ); // 遍历res数组,获取每个元素 [地址id,地区标题] $.each(res, function (index, item) { id = item[0]; atitle = item[1]; option_str = '<option value="' + id + '">' + atitle + '</option>'; city.append(option_str) }) }) }); // 3 绑定city下拉列表框的change事件 $('#city').change(function () { // 发起AJAX请求,获得所有市下面区级的信息 // 获取点击省的id city_id = $(this).val(); $.get('/dis' + city_id, function (data) { res = data.data; // 获取返回的json数据 dis = $('#dis'); // 清空 下拉列表 dis.empty().append( '<option value="">----请选择县----</option>' ); // 遍历res数组,获取每个元素 [地址id,地区标题] $.each(res, function (index, item) { id = item[0]; atitle = item[1]; option_str = '<option value="' + id + '">' + atitle + '</option>'; dis.append(option_str) }) }) }) </script> </body> </html>

def areas(request): '''省市县案例''' return render(request, 'booktest/areas.html') def prov(request): areas = AreaInfo.objects.filter(aParent__isnull=True) # 遍历areas并拼接处json数据 areas_list = [] for area in areas: areas_list.append((area.id, area.atitle)) return JsonResponse({'data': areas_list}) def city(request, pid): '''获取pid下级地区的信息''' areas = AreaInfo.objects.filter(aParent__id=pid) # 遍历areas并拼接处json数据 areas_list = [] for area in areas: areas_list.append((area.id, area.atitle)) return JsonResponse({'data': areas_list}) def dis(request, pid): '''获取pid下级地区的信息''' areas = AreaInfo.objects.filter(aParent__id=pid) # 遍历areas并拼接处json数据 areas_list = [] for area in areas: areas_list.append((area.id, area.atitle)) return JsonResponse({'data': areas_list})