其他技术
-
1. 静态文件
1.1 使用
在 网页使用的css文件,js文件和图片叫做静态文件。
1) 新建静态文件夹 static。
2) 配置静态文件所在的物理目录。Settings.py
STATIC_URL = '/static/' ## 设置静态文件的物理目录 STATICFILES_DIRS = [os.path.join(BASE_DIR,'static')]
STATIC_URL设置访问静态文件对应的url。
STATICFILES_DIRS设置静态文件所在的物理目录。
动态生成静态文件的路径。
<!DOCTYPE html> {% load staticfiles %} <html lang="en"> <head> <meta charset="UTF-8"> <title>静态文件</title> </head> <body> <img src="/static/image/mm.jpg" alt="美女"> <p>动态生成静态文件路径:</p> <img src="{% static 'image/mm.jpg' %}" alt="美女"> </body> </html>
1.2 加载目录
STATICFILES_FINDERS=('django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder')
顺序:先从项目中的static文件中找,找不到再去APP(应用中)的static文件中找
-
2. 中间件
中间件函数是django框架给我们预留的函数接口,让我们可以干预请求和应答的过程。
2.1 获取浏览器端的ip地址
使用request对象的META属性:request.META['REMOTE_ADDR']
2.2 使用中间件
1) 新建middleware.py文件。
2) 定义中间件类。
在类中定义中间件预留函数。
__init__:服务器响应第一个请求的时候调用。
process_request:是在产生request对象,进行url匹配之前调用。
process_view:是url匹配之后,调用视图函数之前。
process_response:视图函数调用之后,内容返回给浏览器之前。
process_exception:视图函数出现异常,会调用这个函数。
如果注册的多个中间件类中包含process_exception函数的时候,调用的顺序跟注册的顺序是相反的。
3) 注册中间件类。
-
3. Admin后台管理
3.1 使用
1) 本地化。语言和时区本地化。
2) 创建超级管理员。
python mange.py createsuperuser
3) 注册模型类。
4) 自定义管理页面。
自定义模型管理类。
注册模型类的时候给register函数添加第二个参数,就是自定义模型管理类的名字。
1 class AreaInfo_Admin(admin.ModelAdmin): 2 '''地区模型类''' 3 ## 指定每页显示10条数据 4 list_per_page = 10 5 list_display = ['id','atitle','title']## 调用title这个方法 6 7 ## 给管理页面底部增加删除按钮 8 actions_on_bottom = True 9 10 ## 删除管理页面顶部的删除按钮 11 actions_on_top = False 12 13 ## 列表页右侧过滤栏 14 list_filter = ['aParent'] 15 16 ## 列表页上方的搜索框 17 search_fields = ['atitle']
1 class AreaInfo(models.Model): 2 '''地区模型类''' 3 ## 地区名 4 atitle = models.CharField(verbose_name='地区名',max_length=20) ## 修改管理页面atitle的默认标题,改为地区名 5 ## 关联属性,代表父级地区,自关联 6 aParent = models.ForeignKey('self',null=True,blank=True,on_delete='CASCADE') 7 8 def title(self): 9 ## 定义方法,让管理类调用 10 return self.atitle 11 ## 将title这个方法变为可选,按atitle排序 12 title.admin_order_field = 'atitle' 13 14 ## 改变管理页面title标题的显示方式,改为中文 15 title.short_description = '地区名称'
3.2 模型管理类相关属性
1) 列表页相关的选项。
2) 编辑页相关的选项。
-
4. 上传图片
商品销售网站。
4.1 配置上传文件保存目录
1) 新建上传文件保存目录。
2) 配置上传文件保存目录。
4.2 后台管理页面上传图片
1) 设计模型类。
2) 迁移生成表格。
3) 注册模型类。
4.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 %} <p><input type="file" name="pic"></p> <p><input type="submit" value="提交"></p> </form> </body> </html>
2) 定义接收上传文件的视图函数。
request对象有一个FILES的属性,类似于字典,通过request.FILES可以获取上传文件的处理对象。
在django中,上传文件不大于2.5M,文件放在内存中。上传文件大于2.5M,文件内容写到一个临时文件中。
Django处理上传文件的两个类:
FILE_UPLOAD_HANDLERS= ("django.core.files.uploadhandler.MemoryFileUploadHandler",
"django.core.files.uploadhandler.TemporaryFileUploadHandler")
1 def upload_handle(request): 2 '''上传图片处理''' 3 ## 1、接收上传的图片 4 pic = request.FILES['pic'] ## 这个一个对象 5 pic_name = pic.name ## 图片的名字 6 # pic.chunks() ## 图片内容,是一个迭代器 7 8 ## 2、打开一个static/media/booktest的文件 9 save_path = '%s/booktest/%s'%(settings.MEDIA_ROOT,pic_name) 10 11 ## 3、写入图片 12 with open(save_path,'wb') as f: 13 for context in pic.chunks(): 14 f.write(context) 15 16 ## 4、往数据库保存记录 17 Pictest.objects.create(goods_pic='booktest/%s'%pic_name) 18 19 ## 5、返回应答 20 return HttpResponse('ok')
上传图片参考资料:
- http://python.usyiyi.cn/documents/django_182/topics/http/file-uploads.html
- http://python.usyiyi.cn/documents/django_182/ref/files/uploads.html#django.core.files.uploadedfile.UploadedFile
-
5. 分页
查询出所有省级地区的信息,显示在页面上。
AeroInfo.objects.filter(aParent__isnull = True)
1) 查询出所有省级地区的信息。
2) 按每页显示10条信息进行分页,默认显示第一页的信息,下面并显示出页码。
3) 点击i页链接的时候,就显示第i页的省级地区信息。
from django.core.paginator import Paginator
paginator = Paginator(areas, 10) #按每页10条数据进行分页
Paginator类对象的属性:
属性名 |
说明 |
num_pages |
返回分页之后的总页数 |
page_range |
返回分页后页码的列表 |
Paginator类对象的方法:
方法名 |
说明 |
page(self, number) |
返回第number页的Page类实例对象 |
Page类对象的属性:
属性名 |
说明 |
number |
返回当前页的页码 |
object_list |
返回包含当前页的数据的查询集 |
paginator |
返回对应的Paginator类对象 |
Page类对象的方法:
属性名 |
说明 |
has_previous |
判断当前页是否有前一页 |
has_next |
判断当前页是否有下一页 |
previous_page_number |
返回前一页的页码 |
next_page_number |
返回下一页的页码 |
1 from django.core.paginator import Paginator 2 ## /show_area(d*) 3 def show_area(request,pindex): 4 '''显示省级地区''' 5 ## 获取省级地区 6 areas = AreaInfo.objects.filter(aParent__isnull=True) 7 ## 分页,每页显示10条 8 paginator = Paginator(areas,10) 9 ## 判断pindex是否为空 10 if pindex == '': 11 pindex = 1 12 else: 13 pindex = int(pindex) 14 15 ## 获取第一页的内容 16 ## page是Page类的实例对象 17 page = paginator.page(pindex) 18 19 ## 返回应答 20 # return render(request,'booktest/show_area.html',{'areas':areas}) 21 return render(request,'booktest/show_area.html',{'page':page})
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>分页</title> 6 </head> 7 <body> 8 <ul> 9 {% for area in page.object_list %} 10 <li>{{ area.atitle }}</li> 11 {% endfor %} 12 </ul> 13 14 <ul> 15 {% if page.has_previous %} 16 <a href="/show_area{{page.previous_page_number}}">上一页</a> 17 {% endif %} 18 {% for pindex in page.paginator.page_range %} 19 {% if pindex == page.number %} 20 {{ pindex }} 21 {%else%} 22 <a href="/show_area{{ pindex }}">{{ pindex }}</a> 23 {% endif %} 24 {% endfor %} 25 {% if page.has_next %} 26 <a href="/show_area{{page.next_page_number}}">下一页</a> 27 {% endif %} 28 </ul> 29 30 </body> 31 </html>
分页参考资料:
http://python.usyiyi.cn/translate/django_182/topics/pagination.html
-
6. 省市县选择案例
1) 显示省地区信息。
$.get('/prov', function(data){
})
2) 省改变时在对应的下拉列表框中显示下级市的信息。
$.get('/city?pid='+pid, function(data){
})
request.GET.get(‘pid’)
或者:
$.get('/city'+$(this).val(), function(data){
})
3) 市改变时在对应的下拉列表框中显示下级县的信息。
$.get('/dis?pid='+pid, function(data){
})
或者:
$.get('/dis'+$(this).val(), function(data){
})
1 def areas(request): 2 '''省市县选择框''' 3 return render(request,'booktest/areas.html') 4 5 def prov(request): 6 '''省份ajax处理''' 7 ## 1、获取所有的省份 8 provs = AreaInfo.objects.filter(aParent__isnull=True) 9 10 ## 2、将所有的省份遍历 11 prov_lists = [] 12 for prov in provs: 13 prov_list = [prov.id,prov.atitle] 14 prov_lists.append(prov_list) 15 16 ## json系列化发送 17 return JsonResponse({'data':prov_lists}) 18 19 def city(request,prov_id): 20 '''市级ajax处理''' 21 ## 1、获取所有的市 22 ## 第一种获取方式 23 # prov = AreaInfo.objects.get(id=prov_id) 24 # citys = prov.areainfo_set.all() 25 ## 第二种方式 26 citys = AreaInfo.objects.filter(aParent__id=prov_id) 27 28 ## 2、将所有市举行遍历 29 city_lists = [] 30 for city in citys: 31 city_list = [city.id,city.atitle] 32 city_lists.append(city_list) 33 34 ## 3、json序列化发送 35 return JsonResponse({'data':city_lists}) 36 37 def county(request,city_id): 38 '''县级ajax处理''' 39 ## 1、获取所有的县 40 41 countys = AreaInfo.objects.filter(aParent__id=city_id) 42 43 ## 2、将所有市举行遍历 44 county_lists = [] 45 for city in countys: 46 county_list = [city.id,city.atitle] 47 county_lists.append(county_list) 48 49 ## 3、json序列化发送 50 return JsonResponse({'data':county_lists})
1 from django.conf.urls import url 2 from booktest import views 3 4 urlpatterns = [ 5 url(r'^areas$',views.areas),## 显示省市县 6 url(r'^prov$',views.prov),## 省级获取ajax 7 url(r'^city(?P<prov_id>d+)$',views.city),## 市级获取ajax 8 url(r'^county(?P<city_id>d+)$',views.county),## 市级获取ajax 9 ]
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>省市县选择</title> 6 </head> 7 <body> 8 9 <select name="prov" id="prov"> 10 <option>--请选择省份--</option> 11 </select> 12 <select name="city" id="city"> 13 <option>--请选择市--</option> 14 </select> 15 <select name="county" id="county"> 16 <option>--请选择县--</option> 17 </select> 18 19 </body> 20 <script src="/static/js/jquery-3.5.0.min.js"></script> 21 <script> 22 //ajax请求方式:get 23 $.get('/prov', function (data) { 24 25 var prov_lists = data['data']; 26 27 //第二种遍历方式:each 28 $(prov_lists).each(function () { 29 var pro_option = $('<option>'); 30 pro_option.html($(this)[1]).val($(this)[0]); 31 $('#prov').append(pro_option); 32 }); 33 34 }); 35 36 37 // 获取省下面的市 38 $('#prov').change(function () { 39 // 清空市和县 40 $('#city').empty().append('<option>--请选择市--</option>'); 41 $('#county').empty().append('<option>--请选择县--</option>'); 42 // 捕获该省级的id 43 var prov_id = $(this).val(); 44 //ajax请求方式:get /city(d+) 45 $.get('/city' + prov_id, function (data) { 46 var city_lists = data['data']; //获取city的列表 47 $(city_lists).each(function () { 48 var city_option = $('<option>'); 49 city_option.html($(this)[1]).val($(this)[0]); 50 $('#city').append(city_option); 51 }); 52 53 }); 54 }); 55 56 57 58 // 获取市下面的县 59 $('#city').change(function () { 60 // 清空#prov 的所有子标签 61 $('#county').empty().append('<option>--请选择县--</option>'); 62 // 捕获该市级的id 63 var city_id = $(this).val(); 64 //ajax请求方式:get /city(d+) 65 $.get('/county' + city_id, function (data) { 66 var county_lists = data['data']; //获取county的列表 67 $(county_lists).each(function () { 68 var county_option = $('<option>'); 69 county_option.html($(this)[1]).val($(this)[0]); 70 $('#county').append(county_option); 71 }); 72 }); 73 }); 74 75 </script> 76 </html>