广东冬至吃什么,湖南长沙移动营业厅,健康之路糖尿病视频
mvc框架的核心思想是:解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容
在orm框架中,它帮我们把类和数据表进行了一个映射,可以让我们通过类和类对象就能操作它所对应的表格中的数据。orm框架还有一个功能,它可以根据我们设计的类自动帮我们生成数据库中的表格,省去了我们自己建表的过程
说明:不需要定义主键列,在生成时会自动添加,并且值为自动增长
数据表的默认名称为:<app_name>_<model_name>
一对多的关系(foreignkey)应定义在多的那个类中
登录后台管理后,默认没有我们创建的应用中定义的模型类,需要在自己应用中的admin.py文件中注册,才可以在后台管理中看到,并进行增删改查操作
django提供了自定义管理页面的功能,比如列表页要显示哪些值
1 from django.contrib import admin 2 from booktest.models import bookinfo,heroinfo 3 4 class bookinfoadmin(admin.modeladmin): 5 list_display = ['id', 'btitle', 'bpub_date'] 6 class heroinfoadmin(admin.modeladmin): 7 list_display = ['id', 'hname','hgender','hcomment'] 8 9 admin.site.register(bookinfo,bookinfoadmin) 10 admin.site.register(heroinfo,heroinfoadmin)
/settings.py文件,找到databases项,默认使用sqlite3数据库
修改为使用mysql数据库,代码如下: 将引擎改为mysql,提供连接的主机host、端口port、数据库名name、用户名user、密码password。
databases = {
'default': {
'engine': 'django.db.backends.mysql',
'name': 'test2', #数据库名字,
'user': 'root', #数据库登录用户名
'password': 'mysql', #数据库登录密码
'host': 'localhost', #数据库所在主机
'port': '3306', #数据库端口
}
}
注意:数据库test2 django框架不会自动生成,需要我们自己进入mysql数据库去创建
使用时需要引入django.db.models包,字段类型如下:
autofield:自动增长的integerfield,通常不用指定,不指定时django会自动创建属性名为id的自动增长属性。
booleanfield:布尔字段,值为true或false。
nullbooleanfield:支持null、true、false三种值。
charfield(max_length=字符长度):字符串。
参数max_length表示最大字符个数。
textfield:大文本字段,一般超过4000个字符时使用。
integerfield:整数。
decimalfield(max_digits=none, decimal_places=none):十进制浮点数。
参数max_digits表示总位数。
参数decimal_places表示小数位数。
floatfield:浮点数。
datefield[auto_now=false, auto_now_add=false]):日期。
参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false。
参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false。
参数auto_now_add和auto_now是相互排斥的,组合将会发生错误。
timefield:时间,参数同datefield。
datetimefield:日期时间,参数同datefield。
filefield:上传文件字段。
imagefield:继承于filefield,对上传的内容进行校验,确保是有效的图片。
通过选项实现对字段的约束,选项如下:
null:如果为true,表示允许为空,默认值是false。
blank:如果为true,则该字段允许为空白,默认值是false。
对比:null是数据库范畴的概念,blank是表单验证范畴的。
db_column:字段的名称,如果未指定,则使用属性的名称。
db_index:若值为true, 则在表中会为此字段创建索引,默认值是false。
default:默认值。
primary_key:若为true,则该字段会成为模型的主键字段,默认值是false,一般作为autofield的选项使用。
unique:如果为true, 这个字段在表中必须有唯一值,默认值是false。
1 list=bookinfo.objects.filter(id__exact=1) 2 可简写为: 3 list=bookinfo.objects.filter(id=1)
说明:如果要包含%无需转义,直接写即可
list = bookinfo.objects.filter(btitle__contains='传')
1 list = bookinfo.objects.filter(btitle__endswith='部')
以上运算符都区分大小写,在这些运算符前加上i表示不区分大小写,如iexact、icontains、istartswith、iendswith
list = bookinfo.objects.filter(btitle__isnull=false)
1 list = bookinfo.objects.filter(id__in=[1, 3, 5])
list = bookinfo.objects.filter(id__gt=3)
1 list = bookinfo.objects.exclude(id=3)
list = bookinfo.objects.filter(bpub_date__year=1980) list = bookinfo.objects.filter(bpub_date__gt=date(1990, 1, 1))
两个属性比较使用f对象
1 list = bookinfo.objects.filter(bread__gte=f('bcomment')) 2 list = bookinfo.objects.filter(bread__gt=f('bcomment') * 2)
多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字
1 list=bookinfo.objects.filter(bread__gt=20,id__lt=3) 2 或 3 list=bookinfo.objects.filter(bread__gt=20).filter(id__lt=3) 4 5 list = bookinfo.objects.filter(q(bread__gt=20) | q(pk__lt=3)) 6 7 q对象前可以使用~操作符,表示非not 8 list = bookinfo.objects.filter(~q(pk=3))
使用aggregate()过滤器调用聚合函数。聚合函数包括:avg,count,max,min,sum,被定义在django.db.models中
list = bookinfo.objects.aggregate(sum('bread'))
注意aggregate的返回值是一个字典类型,格式如下:
{'聚合类小写__属性名':值} 如:{'sum__bread':3}
使用count时一般不使用aggregate()过滤器,count函数的返回值是一个数字
list = bookinfo.objects.count()
all():返回所有数据。
filter():返回满足条件的数据。
exclude():返回满足条件之外的数据,相当于sql语句中where部分的not关键字。
order_by():对结果进行排序
get():返回单个满足条件的对象
如果未找到会引发"模型类.doesnotexist"异常。
如果多条被返回,会引发"模型类.multipleobjectsreturned"异常。
count():返回当前查询结果的总条数。
aggregate():聚合,返回一个字典。
exists():判断查询集中是否有数据,如果有则返回true,没有则返回false
惰性执行:创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用。 缓存:使用同一个查询集,第一次使用时会发生数据库的查询,然后把结果缓存下来,再次使用这个查询集时会使用缓存的数据
每个查询集都包含一个缓存来最小化对数据库的访问。 在新建的查询集中,缓存为空,首次对查询集求值时,会发生数据库查询,django会将查询的结果存在查询集的缓存中,并返回请求的结果,接下来对查询集求值将重用缓存中的结果。
可以对查询集进行取下标或切片操作,等同于sql中的limit和offset子句。
注意:不支持负数索引。
对查询集进行切片后返回一个新的查询集,不会立即执行查询。
如果获取一个对象,直接使用[0],等同于[0:1].get(),但是如果没有数据,[0]引发indexerror异常,[0:1].get()如果没有数据引发doesnotexist异常。
示例:获取第1、2项,运行查看。
list=bookinfo.objects.all()[0:2]
#定义图书模型类bookinfo
class bookinfo(models.model):
...
#定义元选项
class meta:
db_table='bookinfo' #指定bookinfo生成的数据表名为bookinfo
1 url(r'^delete(\d+)/$',views.show_arg) 2 def show_arg(request,id): 3 return httpresponse('show arg %s'%id)
1 url(r'^delete(?p<id1>\d+)/$',views.show_arg) 2 def show_arg(request,id1): 3 return httpresponse('show %s'%id1)
下面除非特别说明,属性都是只读的
path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
method:一个字符串,表示请求使用的http方法,常用值包括:'get'、'post'。
在浏览器中给出地址发出请求采用get方式,如超链接。
在浏览器中点击表单的提交按钮发起请求,如果表单的method设置为post则为post请求。
encoding:一个字符串,表示提交的数据的编码方式。
如果为none则表示使用浏览器的默认设置,一般为utf-8。
这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
get:querydict类型对象,类似于字典,包含get请求方式的所有参数。
post:querydict类型对象,类似于字典,包含post请求方式的所有参数。
files:一个类似于字典的对象,包含所有的上传文件。
cookies:一个标准的python字典,包含所有的cookie,键和值都为字符串。
session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当django 启用会话的支持时才可用,详细内容见"状态保持"。
content:表示返回的内容。
charset:表示response采用的编码字符集,默认为utf-8。
status_code:返回的http响应状态码。
content-type:指定返回数据的的mime类型,默认为'text/html'。
_init_:创建httpresponse对象后完成返回内容的初始化。
set_cookie:设置cookie信息。
set_cookie(key, value='', max_age=none, expires=none)
cookie是网站以键值对格式存储在浏览器中的一段纯文本信息,用于实现用户跟踪。
max_age是一个整数,表示在指定秒数后过期。
expires是一个datetime或timedelta对象,会话将在这个指定的日期/时间过期。
max_age与expires二选一。
如果不指定过期时间,在关闭浏览器时cookie会过期。
delete_cookie(key):删除指定的key的cookie,如果key不存在则什么也不发生。
write:向响应体中写数据。
有时需要保存下来用户浏览的状态,比如用户是否登录过,浏览过哪些商品等。 实现状态保持主要有两种方式
response.set_cookie('h1', '你好')
response.write('<h1>' + request.cookies['h1'] + '</h1>')
在服务器端进行状态保持的方案就是session
django项目默认启用session
/settings.py文件,设置session_engine项指定session数据存储的方式,可以存储在数据库、缓存、redis等
session_engine='django.contrib.sessions.backends.db'
session_engine='django.contrib.sessions.backends.cache'
session_engine='django.contrib.sessions.backends.cached_db'
所有请求者的session都会存储在服务器中,服务器如何区分请求者和session数据的对应关系呢?
在使用session后,会在cookie中存储一个sessionid的数据,每次请求时浏览器都会将这个数据发给服务器,服务器在接收到sessionid后,会根据这个值找出这个请求者的session
结果:如果想使用session,浏览器必须支持cookie,否则就无法使用session了
存储session时,键与cookie中的sessionid相同,值是开发人员设置的键值对信息,进行了base64编码,过期时间由开发人员设置
通过httprequest对象的session属性进行会话的读写操作
request.session['键']=值
request.session.get('键',默认值)
request.session.clear()
request.session.flush()
del request.session['键']
设置会话的超时时间,如果没有指定过期时间则两个星期后过期
会话还支持文件、纯cookie、memcached、redis等方式存储
pip install django-redis-sessions==0.5.6
session_engine = 'redis_sessions.session' session_redis_host = 'localhost' session_redis_port = 6379 session_redis_db = 2 session_redis_password = '' session_redis_prefix = 'session'
for标签语法如下:
{%for item in 列表%}
循环逻辑
{{forloop.counter}}表示当前是第几次循环,从1开始
{%empty%}
列表为空或不存在时执行此逻辑
{%endfor%}
if标签语法如下:
{%if ...%}
逻辑1
{%elif ...%}
逻辑2
{%else%}
逻辑3
{%endif%}
变量|过滤器:参数
data|default:'默认值'
日期date,用于对日期类型的值进行字符串格式化,常用的格式化字符如下:
y表示年,格式为4位,y表示两位的年。
m表示月,格式为01,02,12等。
d表示日, 格式为01,02等。
j表示日,格式为1,2等。
h表示时,24进制,h表示12进制的时。
i表示分,为0-59。
s表示秒,为0-59。
value|date:"y年m月j日 h时i分s秒"
过滤器escape可以实现对变量的html转义,默认模板就会转义,一般省略
{{t1|escape}}
过滤器safe:禁用转义,告诉模板这个变量是安全的,可以解释执行
{{data|safe}}
标签autoescape:设置一段代码都禁用转义,接受on、off参数
{%autoescape off%} ... {%endautoescape%}
csrf全拼为cross site request forgery,译为跨站请求伪造。csrf指攻击者盗用了你的身份,以你的名义发送恶意请求
1 from pil import image, imagedraw, imagefont 2 from django.utils.six import bytesio 3 ... 4 def verify_code(request): 5 #引入随机函数模块 6 import random 7 #定义变量,用于画面的背景色、宽、高 8 bgcolor = (random.randrange(20, 100), random.randrange( 9 20, 100), 255) 10 width = 100 11 height = 25 12 #创建画面对象 13 im = image.new('rgb', (width, height), bgcolor) 14 #创建画笔对象 15 draw = imagedraw.draw(im) 16 #调用画笔的point()函数绘制噪点 17 for i in range(0, 100): 18 xy = (random.randrange(0, width), random.randrange(0, height)) 19 fill = (random.randrange(0, 255), 255, random.randrange(0, 255)) 20 draw.point(xy, fill=fill) 21 #定义验证码的备选值 22 str1 = 'abcd123efghijk456lmnopqrs789tuvwxyz0' 23 #随机选取4个值作为验证码 24 rand_str = '' 25 for i in range(0, 4): 26 rand_str += str1[random.randrange(0, len(str1))] 27 #构造字体对象,ubuntu的字体路径为“/usr/share/fonts/truetype/freefont” 28 font = imagefont.truetype('freemono.ttf', 23) 29 #构造字体颜色 30 fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255)) 31 #绘制4个字 32 draw.text((5, 2), rand_str[0], font=font, fill=fontcolor) 33 draw.text((25, 2), rand_str[1], font=font, fill=fontcolor) 34 draw.text((50, 2), rand_str[2], font=font, fill=fontcolor) 35 draw.text((75, 2), rand_str[3], font=font, fill=fontcolor) 36 #释放画笔 37 del draw 38 #存入session,用于做进一步验证 39 request.session['verifycode'] = rand_str 40 #内存文件操作 41 buf = bytesio() 42 #将图片保存在内存中,文件类型为png 43 im.save(buf, 'png') 44 #将内存中的图片数据返回给客户端,mime类型为图片png 45 return httpresponse(buf.getvalue(), 'image/png')
1 def verify_yz(request): 2 yzm=request.post.get('yzm') 3 verifycode=request.session['verifycode'] 4 response=httpresponse('no') 5 if yzm==verifycode: 6 response=httpresponse('ok') 7 return response
<script type="text/javascript" src="/static/jquery-1.12.4.min.js"></script> <script type="text/javascript"> $(function(){ $('#change').css('cursor','pointer').click(function() { $('#yzm').attr('src',$('#yzm').attr('src')+1) }); }); </script> ... <img id="yzm" src="/verify_code/?1"/> <span id="change">看不清,换一个</span>
在定义url时,需要为include定义namespace属性,为url定义name属性,使用时,在模板中使用url标签,在视图中使用reverse函数,根据正则表达式动态生成地址,减轻后期维护成本
url(r'^',include('booktest.urls',namespace='booktest'))
url(r'^fan2/$', views.fan2,name='fan2')
反向解析:<a href="{%url 'booktest:fan2'%}">fan2</a>
return redirect(reverse('booktest:fan2'))
static_url = '/static/' staticfiles_dirs = [ os.path.join(base_dir, 'static'), ]
方法_init_(列表,int):返回分页对象,第一个参数为列表数据,第二个参数为每页数据的条数。
属性count:返回对象总数。
属性num_pages:返回页面总数。
属性page_range:返回页码列表,从1开始,例如[1, 2, 3, 4]。
方法page(m):返回page类实例对象,表示第m页的数据,下标以1开始
调用paginator对象的page()方法返回page对象,不需要手动构造。
属性object_list:返回当前页对象的列表。
属性number:返回当前是第几页,从1开始。
属性paginator:当前页对应的paginator对象。
方法has_next():如果有下一页返回true。
方法has_previous():如果有上一页返回true。
方法len():返回当前页面对象的个数。
1 from django.core.paginator import paginator 2 from booktest.models import areainfo 3 ... 4 #参数pindex表示:当前要显示的页码 5 def page_test(request,pindex): 6 #查询所有的地区信息 7 list1 = areainfo.objects.filter(aparent__isnull=true) 8 #将地区信息按一页10条进行分页 9 p = paginator(list1, 10) 10 #如果当前没有传递页码信息,则认为是第一页,这样写是为了请求第一页时可以不写页码 11 if pindex == '': 12 pindex = '1' 13 #通过url匹配的参数都是字符串类型,转换成int类型 14 pindex = int(pindex) 15 #获取第pindex页的数据 16 list2 = p.page(pindex) 17 #获取所有的页码信息 18 plist = p.page_range 19 #将当前页码、当前页的数据、页码信息传递到模板中 20 return render(request, 'booktest/page_test.html', {'list': list2, 'plist': plist, 'pindex': pindex})
url(r'^page(?p<pindex>[0-9]*)/$', views.page_test)
<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>
1 <html> 2 <head> 3 <title>省市区列表</title> 4 <script type="text/javascript" src="/static/js/jquery-1.12.4.min.js"></script> 5 <script type="text/javascript"> 6 $(function(){ 7 //页面加载完成后获取省信息,并添加到省select 8 $.get('/area2/',function(dic) { 9 pro=$('#pro') 10 $.each(dic.data,function(index,item){ 11 pro.append('<option value='+item[0]+'>'+item[1]+'</option>'); 12 }) 13 }); 14 //为省select绑定change事件,获取市信息,并添加到市select 15 $('#pro').change(function(){ 16 $.get('/area3_'+$(this).val()+'/',function(dic){ 17 city=$('#city'); 18 city.empty().append('<option value="">请选择市</option>'); 19 dis=$('#dis'); 20 dis.empty().append('<option value="">请选择区县</option>'); 21 $.each(dic.data,function(index,item){ 22 city.append('<option value='+item[0]+'>'+item[1]+'</option>'); 23 }) 24 }); 25 }); 26 //为市select绑定change事件,获取区县信息,并添加到区县select 27 $('#city').change(function(){ 28 $.get('/area3_'+$(this).val()+'/',function(dic){ 29 dis=$('#dis'); 30 dis.empty().append('<option value="">请选择区县</option>'); 31 $.each(dic.data,function(index,item){ 32 dis.append('<option value='+item[0]+'>'+item[1]+'</option>'); 33 }) 34 }) 35 }); 36 37 }); 38 </script> 39 </head> 40 <body> 41 <select id="pro"> 42 <option value="">请选择省</option> 43 </select> 44 <select id="city"> 45 <option value="">请选择市</option> 46 </select> 47 <select id="dis"> 48 <option value="">请选择区县</option> 49 </select> 50 </body> 51 </html
情景:用户发起request,并等待response返回。在本些views中,可能需要执行一段耗时的程序,那么用户就会等待很长时间,造成不好的用户体验,比如发送邮件、手机验证码等
installed_apps = ( ... 'djcelery', }
import djcelery djcelery.setup_loader() broker_url = 'redis://127.0.0.1:6379/2'
1 import time 2 from celery import task 3 4 @task 5 def sayhello(): 6 print('hello ...') 7 time.sleep(2) 8 print('world ...')
1 from booktest import tasks 2 ... 3 def sayhello(request): 4 # print('hello ...') 5 # time.sleep(2) 6 # print('world ...') 7 tasks.sayhello.delay() 8 return httpresponse("hello world")
python manage.py migrate
sudo service redis start
python manage.py celery worker --loglevel=info
1 from django.conf import settings 2 from django.core.mail import send_mail 3 from celery import task 4 5 @task 6 def sayhello(): 7 msg='<a href="http://www.itcast.cn/subject/pythonzly/index.shtml" target="_blank">点击激活</a>' 8 send_mail('注册激活','',settings.email_from, 9 ['itcast88@163.com'], 10 html_message=msg)
请使用手机"扫一扫"x
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Python 实现将numpy中的nan和inf,nan替换成对应的均值
python爬虫把url链接编码成gbk2312格式过程解析
网友评论