三大块除了M、V、T,接下来学习一些其它的知识点,这些知识点不在三大块范围内,Django提供了这些功能后,能够帮助咱们更快更好的完成开发。javascript
主要知识点以下:css
项目中的CSS、图片、js都是静态文件。通常会将静态文件放到一个单独的目录中,以方便管理。在html页面中调用时,也须要指定静态文件的路径,Django中提供了一种解析的方式配置静态文件路径。静态文件能够放在项目根目录下,也能够放在应用的目录下,因为有些静态文件在项目中是通用的,因此推荐放在项目的根目录下,方便管理。html
1)在test5/settings.py文件中定义静态文件存放的物理目录。java
STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ]
2)在项目根目录下建立static目录,再建立img、css、js目录。python
3)在booktest/views.py中定义视图static_test。jquery
def static_test(request): return render(request,'booktest/static_test.html')
4)在booktest/urls.py中配置url。ajax
url(r'^static_test/$',views.static_test),
5)在templates/booktest/下建立static_test.html文件。数据库
<html> <head> <title>静态文件</title> </head> <body> <img src="/static/img/sg.png"/> </body> </html>
6)保存图片到static/img/目录下,名称为sg.png。django
为了安全能够经过配置项隐藏真实图片路径,在模板中写成固定路径,后期维护太麻烦,能够使用static标签,根据配置项生成静态文件路径。浏览器
1)修改templates/booktest/static_test.html以下:
<html> <head> <title>静态文件</title> </head> <body> 修改前:<img src="/static/img/sg.png"/> <hr> 修改后:<img src="/abc/img/sg.png"/> <hr> 动态配置: {%load static from staticfiles%} <img src="{%static "img/sg.png" %}"/> </body> </html>
Django中的中间件是一个轻量级、底层的插件系统,能够介入Django的请求和响应处理过程,修改Django的输入或输出。中间件的设计为开发者提供了一种无侵入式的开发方式,加强了Django框架的健壮性,其它的MVC框架也有这个功能,名称为IoC。
Django在中间件中预置了五个方法,这五个方法的区别在于不一样的阶段执行,对输入或输出进行干预,方法以下:
1)初始化:无需任何参数,服务器响应第一个请求的时候调用一次,用于肯定是否启用当前中间件。
def __init__(self): pass
2)处理请求前:在每一个请求上,request对象产生以后,url匹配以前调用,返回None或HttpResponse对象。
def process_request(self, request): pass
3)处理视图前:在每一个请求上,url匹配以后,视图函数调用以前调用,返回None或HttpResponse对象。
def process_view(self, request, view_func, *view_args, **view_kwargs): pass
4)处理响应后:视图函数调用以后,全部响应返回浏览器以前被调用,在每一个请求上调用,返回HttpResponse对象。
def process_response(self, request, response): pass
5)异常处理:当视图抛出异常时调用,在每一个请求上调用,返回一个HttpResponse对象。
def process_exception(self, request,exception): pass
中间件是一个独立的python类,,能够定义这五个方法中的一个或多个。
1)在booktest/目录下建立middleware.py文件,代码以下:
class my_mid: def __init__(self): print '--------------init' def process_request(self,request): print '--------------request' def process_view(self,request, view_func, *view_args, **view_kwargs): print '--------------view' def process_response(self,request, response): print '--------------response' return response
2)在test5/settings.py文件中,向MIDDLEWARE_CLASSES项中注册。
3)修改booktest/views.py中视图index。
def index(request): print '======index======' return render(request,'booktest/index.html')
4)运行服务器,命令行中效果以下图:
3)刷新页面,命令行中效果以下图:
1)在booktest/middleware.py中定义两个异常类以下:
class exp1: def process_exception(self,request,exception): print '--------------exp1' class exp2: def process_exception(self,request,exception): print '--------------exp2'
2)在test5/settings.py文件中,向MIDDLEWARE_CLASSES项中注册。
3)修改booktest/views.py中视图index。
def index(request): print '======index======' raise Exception('自定义异常') return render(request,'booktest/index.html')
总结:若是多个注册的中间件类中都有process_exception的方法,则先注册的后执行
内容发布的部分由网站的管理员负责查看、添加、修改、删除数据,开发这些重复的功能是一件单调乏味、缺少创造力的工做,为此,Django可以根据定义的模型类自动地生成管理模块。
在第一部分对管理站点作了简单介绍,如今作详细讲解。在Django项目中默认启用Admin管理站点。
1)准备工做:建立管理员的用户名和密码。
python manage.py createsuperuser
按提示填写用户名、邮箱、密码。
2)使用:在应用的admin.py中注册模型类
例:打开booktest/admin.py文件,注册地区模型。
from django.contrib import admin from booktest.models import * admin.site.register(AreaInfo)
3)输入以下网址:
登陆成功后,能够看到AreaInfos,能够进行增长、修改、删除、查询的管理。
列表页显示效果以下图:
类ModelAdmin能够控制模型在Admin界面中的展现方式,主要包括在列表页的展现方式、添加修改页的展现方式。
1)在booktest/admin.py中,注册模型类前定义管理类AreaAdmin。
class AreaAdmin(admin.ModelAdmin): pass
管理类有两种使用方式:
注册参数:打开booktest/admin.py文件,注册模型类代码以下:
admin.site.register(AreaInfo,AreaAdmin)
装饰器:打开booktest/admin.py文件,在管理类上注册模型类,代码以下:
@admin.register(AreaInfo) class AreaAdmin(admin.ModelAdmin): pass
接下来介绍如何控制列表页、增长修改页展现效果。
每页中显示多少条数据,默认为每页显示100条数据,属性以下:
list_per_page=100
1)打开booktest/admin.py文件,修改AreaAdmin类以下:
class AreaAdmin(admin.ModelAdmin): list_per_page = 10
2)在浏览器中查看区域信息的列表页面,效果以下图:
顶部显示的属性,设置为True在顶部显示,设置为False不在顶部显示,默认为True。
actions_on_top=True
底部显示的属性,设置为True在底部显示,设置为False不在底部显示,默认为False。
actions_on_bottom=False
1)打开booktest/admin.py文件,修改AreaAdmin类以下:
class AreaAdmin(admin.ModelAdmin): ... actions_on_top = True actions_on_bottom = True
2)在浏览器中刷新效果以下图:
属性以下:
list_display=[模型字段1,模型字段2,...]
1)打开booktest/admin.py文件,修改AreaAdmin类以下:
class AreaAdmin(admin.ModelAdmin): ... list_display = ['id','atitle']
2)在浏览器中刷新效果以下图:
点击列头能够进行升序或降序排列。
列能够是模型字段,还能够是模型方法,要求方法有返回值。
1)打开booktest/models.py文件,修改AreaInfo类以下:
class AreaInfo(models.Model): ... def title(self): return self.atitle
2)打开booktest/admin.py文件,修改AreaAdmin类以下:
class AreaAdmin(admin.ModelAdmin): ... list_display = ['id','atitle','title']
3)在浏览器中刷新效果以下图:
方法列是不能排序的,若是须要排序须要为方法指定排序依据。
admin_order_field=模型类字段
1)打开booktest/models.py文件,修改AreaInfo类以下:
class AreaInfo(models.Model): ... def title(self): return self.atitle title.admin_order_field='atitle'
2)在浏览器中刷新效果以下图:
列标题默认为属性或方法的名称,能够经过属性设置。须要先将模型字段封装成方法,再对方法使用这个属性,模型字段不能直接使用这个属性。
short_description='列标题'
1)打开booktest/models.py文件,修改AreaInfo类以下:
class AreaInfo(models.Model): ... title.short_description='区域名称'
2)在浏览器中刷新效果以下图:
没法直接访问关联对象的属性或方法,能够在模型类中封装方法,访问关联对象的成员。
1)打开booktest/models.py文件,修改AreaInfo类以下:
class AreaInfo(models.Model): ... def parent(self): if self.aParent is None: return '' return self.aParent.atitle parent.short_description='父级区域名称'
2)打开booktest/admin.py文件,修改AreaAdmin类以下:
class AreaAdmin(admin.ModelAdmin): ... list_display = ['id','atitle','title','parent']
3)在浏览器中刷新效果以下图:
右侧栏过滤器
属性以下,只能接收字段,会将对应字段的值列出来,用于快速过滤。通常用于有重复值的字段
list_filter=[]
1)打开booktest/admin.py文件,修改AreaAdmin类以下:
class AreaAdmin(admin.ModelAdmin): ... list_filter=['atitle']
2)在浏览器中刷新效果以下图:
属性以下,用于对指定字段的值进行搜索,支持模糊查询。列表类型,表示在这些字段上进行搜索。
search_fields=[]
1)打开booktest/admin.py文件,修改AreaAdmin类以下:
class AreaAdmin(admin.ModelAdmin): ... search_fields=['atitle']
2)在浏览器中刷新效果以下图:
1)打开booktest/models.py文件,修改模型类,为属性指定verbose_name参数,即第一个参数
class AreaInfo(models.Model): atitle=models.CharField('标题',max_length=30)#名称 ...
2)在浏览器中刷新效果以下图:
属性以下:
fields=[]
1)点击某行ID的连接,能够转到修改页面,默认效果以下图:
2)打开booktest/admin.py文件,修改AreaAdmin类以下:
class AreaAdmin(admin.ModelAdmin): ... fields=['aParent','atitle']
3)刷新浏览器效果以下图:
在下拉列表中输出的是对象的名称,能够在模型类中定义str方法用于对象转换字符串。
1)打开booktest/models.py文件,修改AreaInfo类,添加str方法。
class AreaInfo(models.Model): ... def __str__(self): return self.atitle
2)刷新浏览器效果以下图:
属性以下:
fieldset=( ('组1标题',{'fields':('字段1','字段2')}), ('组2标题',{'fields':('字段3','字段4')}), )
1)打开booktest/admin.py文件,修改AreaAdmin类以下:
class AreaAdmin(admin.ModelAdmin): ... # fields=['aParent','atitle'] fieldsets = ( ('基本', {'fields': ['atitle']}), ('高级', {'fields': ['aParent']}) )
2)刷新浏览器效果以下图:
在一对多的关系中,能够在一端的编辑页面中编辑多端的对象,嵌入多端对象的方式包括表格、块两种。 类型InlineModelAdmin:表示在模型的编辑页面嵌入关联模型的编辑。子类TabularInline:以表格的形式嵌入。子类StackedInline:以块的形式嵌入。
1)打开booktest/admin.py文件,建立AreaStackedInline类。
class AreaStackedInline(admin.StackedInline): model = AreaInfo#关联子对象 extra = 2#额外编辑2个子对象
2)打开booktest/admin.py文件,修改AreaAdmin类以下:
class AreaAdmin(admin.ModelAdmin): ... inlines = [AreaStackedInline]
3)刷新浏览器效果以下图:
能够用表格的形式嵌入。
1)打开booktest/admin.py文件,建立AreaTabularInline类。
class AreaTabularInline(admin.TabularInline): model = AreaInfo#关联子对象 extra = 2#额外编辑2个子对象
2)打开booktest/admin.py文件,修改AreaAdmin类以下:
class AreaAdmin(admin.ModelAdmin): ... inlines = [AreaTabularInline]
3)刷新浏览器效果以下图:
在python中进行图片操做,须要安装包PIL。
pip install Pillow==3.4.1
在Django中上传图片包括两种方式:
上传图片后,将图片存储在服务器上,而后将图片的路径存储在表中。
将模型类的属性定义成models.ImageField类型。
1)打开booktest/models.py文件,定义模型类PicTest。
class PicTest(models.Model): pic = models.ImageField(upload_to='booktest/')
2)回到命令行中,生成迁移。
python manage.py makemigrations
3)打开booktest/migrations/0001_initial.py文件,删除AreaInfo部分,由于这个表已经存在。
4)回到命令行中,执行迁移。
python manage.py migrate
5)由于当前没有定义图书、英雄模型类,会提示“是否删除”,输入“no”后回车,表示不删除。
6)打开test5/settings.py文件,设置图片保存路径。
由于图片也属于静态文件,因此保存到static目录下。
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")
1)打开booktest/admin.py文件,注册PicTest。
from django.contrib import admin from booktest.models import * admin.site.register(PicTest)
2)运行服务器,输入以下网址。
3)点击“Add”添加数据,打开新页面。
4)选择图片,点击“save”按钮完成图片上传。 5)回到数据库命令行,查询表pictest中的数据以下图:
1)打开booktest/views.py文件,建立视图pic_upload。
def pic_upload(request): return render(request,'booktest/pic_upload.html')
2)打开booktest/urls.py文件,配置url。
url(r'^pic_upload/$', views.pic_upload),
3)在templates/booktest/目录下建立模板pic_upload.html。
在模板中定义上传表单,要求以下:
<html> <head> <title>自定义上传图片</title> </head> <body> <form method="post" action="/pic_handle/" enctype="multipart/form-data"> {%csrf_token%} <input type="file" name="pic"/><br> <input type="submit" value="上传"> </form> </body> </html>
4)打开booktest/views.py文件,建立视图pic_handle,用于接收表单保存图片。
request对象的FILES属性用于接收请求的文件,包括图片。
from django.conf import settings from django.http import HttpResponse ... def pic_handle(request): f1=request.FILES.get('pic') fname='%s/booktest/%s'%(settings.MEDIA_ROOT,f1.name) with open(fname,'wb') as pic: for c in f1.chunks(): pic.write(c) return HttpResponse('OK')
5)打开booktest/urls.py文件,配置url。
url(r'^pic_handle/$', views.pic_handle),
6)运行服务器
选择文件后点击按钮上传图片。
Django提供了数据分页的类,这些类被定义在django/core/paginator.py中。 类Paginator用于对列进行一页n条数据的分页运算。类Page用于表示第m页的数据。
1)在booktest/views.py文件中建立视图page_test。
from django.core.paginator import Paginator from booktest.models import AreaInfo ... #参数pIndex表示:当前要显示的页码 def page_test(request,pIndex): #查询全部的地区信息 list1 = AreaInfo.objects.filter(aParent__isnull=True) #将地区信息按一页10条进行分页 p = Paginator(list1, 10) #若是当前没有传递页码信息,则认为是第一页,这样写是为了请求第一页时能够不写页码 if pIndex == '': pIndex = '1' #经过url匹配的参数都是字符串类型,转换成int类型 pIndex = int(pIndex) #获取第pIndex页的数据 list2 = p.page(pIndex) #获取全部的页码信息 plist = p.page_range #将当前页码、当前页的数据、页码信息传递到模板中 return render(request, 'booktest/page_test.html', {'list': list2, 'plist': plist, 'pIndex': pIndex})
2)在booktest/urls.py文件中配置url
url(r'^page(?P<pIndex>[0-9]*)/$', views.page_test),
3)在templates/booktest/目录下建立page_test.html模板文件。
<html> <head> <title>分页</title> </head> <body> 显示当前页的地区信息:<br> <ul> {%for area in list%} <li>{{area.id}}--{{area.atitle}}</li> {%endfor%} </ul> <hr> 显示页码信息:当前页码没有连接,其它页码有连接<br> {%for pindex in plist%} {%if pIndex == pindex%} {{pindex}} {%else%} <a href="/page{{pindex}}/">{{pindex}}</a> {%endif%} {%endfor%} </body> </html>
4)运行服务器
5)点击页码数字,效果以下图:
本示例讲解在Django中使用jquery的ajax进行数据交互。 jquery框架中提供了$.ajax、$.get、$.post方法,用于进行异步交互,因为Django中默认使用CSRF约束,推荐使用$.get。
示例:实现省市区的选择。
最终实现效果如图:
1)将jquery文件拷贝到static/js/目录下。
2)打开booktest/views.py文件,定义视图area1,用于显示下拉列表。
#提供显示下拉列表的控件,供用户操做 def area1(request): return render(request,'booktest/area1.html')
3)打开booktest/urls.py文件,配置url。
url(r'^area1/$', views.area1),
4)在templates/booktest/目录下建立area1.html。
<html> <head> <title>省市区列表</title> <script type="text/javascript" src="/static/js/jquery-1.12.4.min.js"></script> <script type="text/javascript"> $(function(){ //页面加载完成后获取省信息,并添加到省select $.get('/area2/',function(dic) { pro=$('#pro') $.each(dic.data,function(index,item){ pro.append('<option value='+item[0]+'>'+item[1]+'</option>'); }) }); //为省select绑定change事件,获取市信息,并添加到市select $('#pro').change(function(){ $.get('/area3_'+$(this).val()+'/',function(dic){ city=$('#city'); city.empty().append('<option value="">请选择市</option>'); dis=$('#dis'); dis.empty().append('<option value="">请选择区县</option>'); $.each(dic.data,function(index,item){ city.append('<option value='+item[0]+'>'+item[1]+'</option>'); }) }); }); //为市select绑定change事件,获取区县信息,并添加到区县select $('#city').change(function(){ $.get('/area3_'+$(this).val()+'/',function(dic){ dis=$('#dis'); dis.empty().append('<option value="">请选择区县</option>'); $.each(dic.data,function(index,item){ dis.append('<option value='+item[0]+'>'+item[1]+'</option>'); }) }) }); }); </script> </head> <body> <select id="pro"> <option value="">请选择省</option> </select> <select id="city"> <option value="">请选择市</option> </select> <select id="dis"> <option value="">请选择区县</option> </select> </body> </html>
5)运行服务器浏览效果以下图:
6)打开booktest/views.py文件,定义视图area2,用于获取省信息。
from django.http import JsonResponse ... #获取省信息 def area2(request): list = AreaInfo.objects.filter(aParent__isnull=True) list2 = [] for item in list: list2.append([item.id, item.atitle]) return JsonResponse({'data': list2})
7)打开booktest/urls.py文件,配置url。
url(r'^area2/$', views.area2),
8)在浏览器中输入网址,浏览效果以下图:
9)打开booktest/views.py文件,定义视图area3,用于根据编号获取对应的子级信息,若是传递的是省编号则获取市信息,若是传递的是市编号则获取区县信息。
#根据pid查询子级区域信息 def area3(request, pid): list = AreaInfo.objects.filter(aParent_id=pid) list2 = [] for item in list: list2.append([item.id, item.atitle]) return JsonResponse({'data': list2})
10)打开booktest/urls.py文件,配置url。
url(r'^area3_(\d+)/$', views.area3),
11)在浏览器中输入以下网址,浏览效果以下图:
12)在浏览器中输入以下网址,选择效果以下图: