目录
管理器
objects是models.Manger类的一个对象,通过管理器对象objects可以实现对数据的查询。
可以自定义管理器对象:
1):在模型models.py里定义一个模型管理器类(bookManeger)继承models.Manger
2):再在具体的模型类(book)里定义一个自定义管理器类的对象myobject=bookManager()。
应用场景:改变查询的结果集,封装函数操作模型类对应的数据表。
元选项
问题:模型类在数据库生成的名字格式为:应用名_模型名,如果改变了应用名,就不能找到对应的表。
解决:元选项,在模型类里指定模型类对应的表名
class BookInfo(models.Model):
.....
#元选项
class Meta:
db_table='bookinfo'#自定义生成的表名
Ajax
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
案例:ajax登录
【login_ajax.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax登录案例</title>
{#引入jQuery#}
<script src="/static/js/jquery.js"></script>
<script>
$(function () {
$('#btnlogin').click(function () {
//1.获取用户名和密码
uname=$('#uname').val()
pwd=$('#pwd').val()
//2.发起ajax请求
$.ajax({
'url':'/myapp1/login_ajax_check',//请求地址
'type':'post',//请求方式
'data':{
'uname':uname,
'pwd':pwd,
#csrf
'csrfmiddlewaretoken':$("input[name='csrfmiddlewaretoken']").val(),
},//请求时带的数据
'dataType':'json',//返回的数据格式
}).success(function (data) {
//登录成功{’res‘:1}
//登录失败{’res‘:0}
if(data.res==0){
$('#errmsg').show().html("用户名或密码错误!!!")
}
else {
//跳转到首页
location.href='/myapp1/index'
}
})
})
})
</script>
<style>
#errmsg{
display: none;
color: red;
}
</style>
</head>
<body>
<div id="login">
{% csrf_token %}
<div id="errmsg"></div>
用户名:<input type="text" id="uname"><br>
密码:<input type="password" id="pwd"><br>
<input type="button" id="btnlogin" value="登录">
</div>
</body>
</html>
【myapp1/urls.py】
from django.urls import path
from myapp1 import views
urlpatterns = [
#首页
path('index/',views.index),
#展示ajax登录页面
path('login_ajax',views.login_ajax),
#判断ajax登录页面的信息,是否登录成功
path('login_ajax_check',views.login_ajax_check)
]
【myapp1/views.py】
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
#首页
def index(request):
context = { }
context['name'] = 'python'
context['list'] = list(range(1,5))
return render(request, 'myapp1/index.html', context)
#显示login_ajax登录页面
def login_ajax(request):
return render(request,'myapp1/login_ajax.html')
##判断ajax登录页面的信息,是否登录成功
def login_ajax_check(request):
#1.获取请求中的用户名,密码
uname=request.GET.get('uname')
pwd = request.GET.get('pwd')
print(uname)
#2.判断用户名和密码
if (uname=="admin" and pwd=="123456"):
# 3.返回
return JsonResponse({"res":1})#成功
else:return JsonResponse({"res":0})#失败
cookie
由服务器生成,存储在浏览器端的一小段文本信息。【安全性要求不高的】
特点:
- 以键值对方式进行存储
- 浏览器访问网站时,会将与该网站相关的所有cookie信息发送给该网站,request.COOKIE,是字典类型
- cookie有过期时间,默认关闭浏览器cookie过期
- cookie基于域名安全
#设置cookie信息
def set_cookie(request):
#需要
response=HttpResponse('设置cookie信息')
#设置一个cookie信息,名字为num,值为1
response.set_cookie('num',123)
return response
#获取cookie
def get_cookie(request):
num=request.COOKIES['num']
return HttpResponse(num)
案例:cookie记住用户名,登录成功后三天内再登录都不用填用户名信息
【myapp1/login_cookie.html】
<form action="/myapp1/login_cookie" method="post">
{% csrf_token %}
用户名:<input type="text" name="uname" value="{{ uname }}"><br>
密码:<input type="password" name="pwd"><br>
<input type="checkbox" name="remember" >记住用户名<br>
<input type="submit" value="登录">
</form>
【myapp1/views.py】
#记住密码登录页面展示
#地址:/myapp1/remember
def remember(request):
#登录时先检查是否有cookie信息
if'uname'in request.COOKIES:
uname=request.COOKIES['uname']
else:
uname=''
return render(request, 'myapp1/login_cookie.html',{'uname':uname})
#利用cookie记住密码
#地址:/myapp1/login_cookie
def login_cookie(request):
# 1.获取提交的用户名和密码,
uname = request.POST.get("uname")
pwd = request.POST.get("pwd")
remember=request.POST.get("remember")
# 2.校验用户名密码
if (uname == "cookie" and pwd == "123456"):
# 3.返回
response=redirect('/myapp1/index')#首页
#用户名,密码正确,判断是否需要记住用户名
if(remember=='on'):
response.set_cookie('uname',uname,max_age=3*24*60*60)#3天有效期
return response
else:
return redirect("/myapp1/remember")#用户名或密码错误,重新登录
session
session特点:【安全性要求较高,银行卡账户,密码】
- 存储在服务器端
- session以键值对进行存储
- session依赖于cookie
- 默认过期时间两周
1):设置session
request.session[" uname "] = '李白'
2):取出session
request.session[" uname "] 或者 request.session.get(" uname " , 默认值)
3):设置过期时间
request.session.set.expiry[ value ]
- value是整数,session_id cookie在value秒后过期
- value为0,session_id cookie浏览器关闭时过期
- value为None,session_id cookie两周后过期
案例:登录成功一次后,三天免登陆,直接跳转到首页
登录装饰器
验证码
URL反向解析
中间件
__init__():服务器重启之后,接收第一个请求时调用。
process_request():产生request对象之后,url匹配之前调用。
process_view():url匹配之后,视图函数调用之前调用。
process_response():视图函数调用之后,内容返回浏览器之前调用。
process_exception():视图发生异常时调用。
使用:
- 新建middleware.py文件
- 定义中间件类
- 注册中间件,在settings.py中的MIDDLEWARE_CLASSES
上传图片
1.配置上传文件保存目录
在static下新建一个文件,在settings.py中设置保存目录
【后台管理页面上传图片】
1)定义模型类,生成迁移文件。models.ImageField( upload_to=' ' )
2)在admin.py中注册模型类
from booktest.models import picTest
admin.site.register(picTest)
3)登录后台管理页面,可以上传图片
【用户上传图片】
1)定义用户上传图片的表单。指定提交方式为post,enctype="multipart/form-data"
<form method="post" action="/booktest/pic_load" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="pic"><br>
<input type="submit" value="上传">
</form>
2)定义解释文件的视图函数
def pic_load(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():
f.write(content)
#4.数据库中保存上传记录(pic)
picTest.objects.create(goods_pic='booktest/%s'%pic.name)
#5.返回
return HttpResponse('ok')
上传文件
页面:
<h2>保存整个文件</h2>
<div id="">
<form method="post" action="/book/f_upload02" enctype="multipart/form-data">
{% csrf_token %}
<div>
<input type="file" name="myfile" multiple="" > <br>
</div>
<button type="submit" > 上传<br>
</form>
</div>
request.FILES
只有在请求方法为POST,并且提交请求的<form>
具有enctype="multipart/form-data"
属性时才有效。 否则,request.FILES
将为空。
view.py
#保存上传的文件
def alltype_upload(request):
if request.method == "POST": # 请求方法为POST时,进行处理
myFile = request.FILES.get("myfile", None) # 获取上传的文件,如果没有文件,则默认为None
if not myFile:
return HttpResponse("请上传文件!")
destination=open(os.path.join('statics\\upload',myFile.name),'wb+') #一定用\\
# destination = open(
# os.path.join("你的文件存放地址", myFile.name),
# 'wb+') # 打开特定的文件进行二进制的写操作
for chunk in myFile.chunks(): # 分块写入文件
destination.write(chunk)
destination.close()
return HttpResponse("upload over!")
获得上传的文件对象:
myFile = request.FILES.get("myfile", None)
myFile = request.FILES['myfile']
不能通过 request.POST.get('myfile'),上传的文件保存在FILES字典中,
上传文件的方法、属性
myFile.read() : 从文件中读取整个上传数据,适用小文件
myFile.chunks() : 按块返回文件,通过for循环迭代,将大文件按块写入服务器
myFile.multiple_chunks() : 根据文件大小,返回True或者False,文件大于2.5M返回True,小于2.5M返回False,
if myFile.multiple_chunks() == False:
#使用myFile.read()
else:
#用myFile.chunks()
myFile.name: 是一个属性,该属性得到包括后缀的文件名,123.txt
myFile.size: 是一个属性,得到上传文件的大小
下载文件
页面:
<h2>下载文件</h2>
<div id="">
<a href="/book/download" rel="external nofollow" >点我下载</a>
</div>
views.py:
#下载文件
def download(request):
file = open('statics\\upload\\down.html', 'rb') #文件路径statics\\upload\\down.html
#方式1:使用HttpResponse
#response = HttpResponse(file)
#方式2:使用StreamingHttpResponse
# response = StreamingHttpResponse(file)
#方式3:FileResponse
response = FileResponse(file)
response['Content-Type'] = 'application/octet-stream' # 设置头信息,告诉浏览器这是个文件
response['Content-Disposition'] = 'attachment;filename="down.html"'
return response
分页
【page.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>分页显示图书信息</title>
</head>
<body>
<h4>图书有:</h4>
<ul>
{% for i in page.object_list %}
<li>{{ i.id }},{{ i.title }},{{ i.pub_data }}</li>
{% endfor %}
</ul>
{#有上一页#}
{% if page.has_previous %}
<a href="/booktest/page{{page.previous_page_number }}">上一页</a>
{% endif %}
{#分页#}
{# page_range获取所有页码,是一个列表 #}
{% for index in page.paginator.page_range %}
{# page.number获取当前页的页码#}
{% if index == page.number %}
{# 为当前页,直接显示 #}
{{ index }}
{% else %}
{# 其他页码显示为超链接 #}
<a href="/booktest/page{{ index }}"> {{ index }}</a>
{% endif %}
{% endfor %}
{#有下一页#}
{% if page.has_next %}
<a href="/booktest/page{{page.next_page_number }}">下一页</a>
{% endif %}
{#页码总数#}
|共有{{ page.paginator.num_pages }}页|
</body>
</html>
【urls.py】
url(r'^page(?P<now_index>\d*)$', views.page),
【views.py】
#分页显示
from django.core.paginator import Paginator
#url(r'^page(?P<now_index>\d*)$', views.page),
# 通过url捕获页码,取名now_index
#now_index当前页码
def page(request,now_index):
#1.查询出所有信息
books=BookInfo.objects.all()
#2.分页,每页3条
paginator=Paginator(books,3)
#3.获取当前页的内容
if now_index=='':
now_index=1#第一页是空字符串
else: now_index=int(now_index)#url捕获的是字符串
page=paginator.page(now_index)
return render(request,'booktest/page.html',{'page':page})