Django学习笔记(2)_管理器,元选项,cookie,session,分页

目录

管理器

元选项

Ajax

session

登录装饰器

验证码

URL反向解析

中间件

上传图片

上传文件

分页


管理器

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})#失败


由服务器生成,存储在浏览器端的一小段文本信息。【安全性要求不高的】

特点:

  1. 以键值对方式进行存储
  2. 浏览器访问网站时,会将与该网站相关的所有cookie信息发送给该网站,request.COOKIE,是字典类型
  3. cookie有过期时间,默认关闭浏览器cookie过期
  4. 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特点:【安全性要求较高,银行卡账户,密码】

  1. 存储在服务器端
  2. session以键值对进行存储
  3. session依赖于cookie
  4. 默认过期时间两周

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():视图发生异常时调用。

使用:

  1. 新建middleware.py文件
  2. 定义中间件类
  3. 注册中间件,在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})

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值