我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python Day18 Django

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python Day18 Django

(1)获取cookie

request.COOKIE

(2)设置cookie

response.set_cookie("","",)

(3)cookie参数

def set_cookie(self, key, value='', max_age=None, expires=None, path='/',
                   domain=None, secure=False, httponly=False):

max_age过期时间(秒)
expires过期时间(接收一个日期对象)
path 设置这个cookie在哪些路径下有效 '/'代表在所有路径下有效
domain 设置这个cookie在哪些域下有效

day12

设置session

request.session["user_id"]=user.pk
request.session["username"]=user.user

设置session方法及原理

第一步:
如果获取到sessionid的值,则更新
if request.COOKIE.get("sessionid"):

第二步:
如果获取不到,就创建一个字符串                  
{"user_id":1,"username":"alex"}

1. 生成随机字符串: vwerascxh24asdasdasdsd(session-key)
2. 在django-sesion表生成一条记录:
    session-key                    session-data
  vwerascxh24asdasdasdsd       {"user_id":1,"username":"alex"}

3. 设置Cookie
    obj.set_cookie("sessionid",vwerascxh24asdasdasdsd) 

这样,下次再访问时通过获取cookie中的"sessionid"的值就可以得到所对应的session-data

django-sesion表中session记录示例:

Python Day18 Django 04

获取session方法及原理

获取语句

request.session.get("user_id")

大概流程

1. 根据网页所携带的cookie获取"sessionid"的值
request.COOKIE.get("sessionid"):vwerascxh24asdasdasdsd

2. 根据"sessionid"的值在django-sesion表查询一条记录:
session-key=vwerascxh24asdasdasdsd

3. 获取session-data中的数据
session-data({"user_id":1,"username":"alex"}).get("user_id")

示例:

def login(request):
    if request.method == "POST":
        user = request.POST.get("name")
        pwd = request.POST.get("pwd")
        user = Userinfo.objects.filter(user=user, pwd=pwd).first()
        res = {"msg": False}
        if user:
            res["msg"] = True
            import json
            obj = HttpResponse(json.dumps(res))
            request.session["user_id"] = user.pk     #设置session
            request.session["username"] = user.user  #设置session
            return obj

    return render(request, "login.html")
def index(request):
    if not request.session.get("user_id"):   #判断是否能获取到session
        return redirect("/login/")

    username = request.session.get("username")  #获取session中"username"的值

    return render(request, "index.html", locals())  #把上面获取到的username的值传给模板

注销session

def logout(request):

    request.session.flush()

    return redirect("/login/")

批量导入数据

在urls.py中创建一个url

url(r'^books/$', views.books)

在models中创建数据表

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)

在视图中,方法1:

from django.shortcuts import render, HttpResponse

# Create your views here.
from app01.models import Book

def books(request):
    book_list = []
    for i in range(100):
        book_obj = Book(title="Book_%s" %i, price=i*i)
        book_list.append(book_obj)

    #会将上面的实例化对象一次插入到表中
    Book.objects.bulk_create(book_list)

    return HttpResponse("OK")

在视图中,方法2:

#批量创建数据
objs = [models.Book(title="沙河{}".format(i)) for i in range(100)]

#在数据库中批量创建,10次一提交
models.Book.objects.bulk_create(objs, 10)

访问:
http://127.0.0.1:8000/books/

分页器的使用

print("count:", paginator.count) # 数据总数
print("num_pages", paginator.num_pages) # 总页数
print("page_range", paginator.page_range) # 页码的列表 返回一个range

page = paginator.page(2) #第2页的page对象

print(page.object_list) #第2页的所有数据
结果:

<QuerySet[ < Book: title_12 >, < Book: title_13 >, < Book: title_14 >...

for i in page: #遍历第1页的所有数据对象
print(i)

结果:
title_12
title_13
title_14
title_15

print(page.has_next()) # 是否有下一页
print(page.next_page_number()) # 下一页的页码
print(page.has_previous()) # 是否有上一页
print(page.previous_page_number()) # 上一页的页码

抛错
page=paginator.page(12) # error:EmptyPage
page=paginator.page("z") # error:PageNotAnInteger

views

from django.shortcuts import render, HttpResponse

from .models import Book
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger        
def index(request):
    # 分页器的使用
    try:
        book_list = Book.objects.all()

        paginator = Paginator(book_list, 12)  # 获得一个总的分页器对象

        # 从url获取page值,如果没有获取就默认1
        c_page = request.GET.get("page", 1)
        # 转换为int类型,不然template识别不了
        currentPage = int(c_page) # 转换为int类型,不然template识别不了
        # 获取page对象
        page = paginator.page(c_page)

    except EmptyPage:
        page = paginator.page(1)

    return render(request, "index.html", locals())

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>分页器</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>

<ul>
    {% for book in page.object_list %}
        <p>{{ book.title }}:{{ book.price }}</p>
    {% endfor %}
</ul>

<nav aria-label="Page navigation">
  <ul class="pagination">
  {% if page.has_previous %}
      <li><a href="?page={{ c_page|add:-1 }}" aria-label="Previous">上一页</a></li>
  {% else %}
      <li class="disabled"><a href="?page={{ c_page|add:-1 }}" aria-label="Previous">上一页</a></li>
  {% endif %}

      {% for num in paginator.page_range %}
          {% if currentPage == num %}
              <li class="active"><a href="?page={{ num }}">{{ num }}</a></li>
          {% else %}
              <li><a href="?page={{ num }}">{{ num }}</a></li>
          {% endif %}
      {% endfor %}

  {% if page.has_next %}
      <li><a href="?page={{ c_page|add:+1 }}" aria-label="Next">下一页</a></li>
  {% else %}
      <li class="disabled"><a href="?page={{ c_page|add:+1 }}" aria-label="Next">下一页</a></li>
  {% endif %}

  </ul>
</nav>

</body>
</html>

显示限定页码数

如果页数过多怎么办?这里保持只显示10个页码
将template中的paginator.page_range(总页数的列表)修改为下面的pageRange,
因为显示页数过多,我们这里指定返还给template的页码数列表(range)

def index(request):

book_list=Book.objects.all()

paginator = Paginator(book_list, 2)
page = request.GET.get('page',1)
currentPage=int(page)

#如果总页数大于30
if paginator.num_pages>30:
    #如果当前页面page的值-5还小于1
    if currentPage-5<1:
        #页码的列表为1-10(pageRange返回给模板)
        pageRange=range(1,11)
    #如果当前页面page的值+5大于总页数
    elif currentPage+5>paginator.num_pages:
        #计算最大页数-10页的页码
        min_page = (paginator.num_pages + 1) - 10
        #计算当前页面所需要减去的页码数
        page_num = currentPage - min_page
        #页码的列表为“当前所在页数-上面计算的页数 至 总页数+1”,正好凑齐10页(pageRange返回给模板)
        pageRange=range(currentPage-page_num,paginator.num_pages+1)

    else:
        #页码的列表为“当前所在页数-5,到当前所在页数+5”(pageRange返回给模板)
        pageRange=range(currentPage-5,currentPage+5)

else:
    #如果总页数小于30,返回给模板实际的页码的列表
    pageRange=paginator.page_range

try:
    #获取当前页面对象
    book_list = paginator.page(page)
except PageNotAnInteger:
    book_list = paginator.page(1)
except EmptyPage:
    book_list = paginator.page(paginator.num_pages)

return render(request,"index.html",locals())

Python Day18 Django 04

Python Day18 Django 04

中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。
因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。

如果你想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。

自定义中间件

中间件中一共有四个方法:

process_request

process_view

process_exception

process_response

process_request,process_response

当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,
views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者

Python Day18 Django 04

上述截图中的中间件都是django中的,我们也可以自己定义一个中间件,我们可以自己写一个类,但是必须继承MiddlewareMixin

settings
自定义中间件放在哪都可以

MIDDLEWARE = [
    '...Django默认的Middleware...'
    'app01.utils.mymiddlewares.M1',  #注意,不要忘了逗号
    'app01.utils.mymiddlewares.M2'
]

in views:

from django.shortcuts import render, HttpResponse

def index(request):
    print("index")
    return HttpResponse("OK")

in Mymiddlewares.py:

from django.utils.deprecation import MiddlewareMixin

from django.shortcuts import HttpResponse

class M1(MiddlewareMixin):   #注意继承MiddlewareMixin类
    def process_request(self, request):
        print("M1 process_request")

    def process_response(self, request, response):
        print("M1 process_response")
        return response      #process_response要返回一个response

class M2(MiddlewareMixin):
    def process_request(self, request):
        print("M2 process_request")

    def process_response(self, request, response):
        print("M2 process_response")
        return response

结果

M1 process_request
M2 process_request
index
M2 process_response
M1 process_response

注意,process_request带有return的情况下会在满足条件时原路返回,等于从中间拦截了,不再往下走。
如果 process_response的return不返回response而且是它的,同样也会产生偷梁换柱的效果,返回给客户端的结果将不会是 views中定义的结果

数据校验

首先在模板中创建一个简单的表单,以获得用户名、邮箱、手机号等

<form action="" method="post" novalidate>
    {% csrf_token %}
    <p>用户名 <input type="text" name="user"></p>
    <p>邮箱 <input type="email" name="email"></p>
    <p>手机号 <input type="text" name="tel"></p>
    <input type="submit">
</form>

此时我们要将用户在网页上填写的内容在视图中拿出来,并做判断
之前我们是使用if request.POST.get取出后进行判断的,这里换成form表单,
方法就是在views新建一个Form类(需要继承forms.Form)
views:

from django import forms

class UserForm(forms.Form):
    user=forms.CharField(min_length=5)  #最少5位
    tel=forms.CharField(max_length=8)   #最长不超过8位
    email=forms.EmailField()            #判断是否是邮箱地址类型

#我们通过上面这个类帮助我们进行数据校验,从而实现功能的分离和复用
def reg(request):

    if request.method == "POST":
        form = UserForm(request.POST) #绑定数据至表单
        if form.is_valid(): 如果form.is_valid()为Ture
            return HttpResponse('OK')
        else:
            return render(request, 'reg.html', {"form": form})

    return render(request, 'reg.html')

表单的is_valid()方法,如果被校验的字段有一个错误,那么就会返回False

备注:

在表单中输入内容,看print(request.POST)能打印出什么
<QueryDict: {
 'csrfmiddlewaretoken': ['Mhzbi6hiHnxVAKG9GEChEzscCo5GUnkuBnH3xmVOQGYfXxCTQUcoCiu9hGIiqRRT'],
 'user': ['dzm'],
 'email': ['335@qq.com'],
 'tel': ['1118']
 }>

form表单数据校验原理

会生成两个字典

form.is_valid():
    # 校验成功的字段
    form.cleaned_data={"user":"alex999","tel":'123'}

    # 校验失败的字段
    form.errors={"email":["..........","......."]} #列表中是错误信息,不再保留key原本的值

可以将他们打印出来
print("====>",form.cleaned_data)
print("====>",form.errors)
其它
print("---->", type(form.errors["user"])) #实际是个字典
print("---->", form.errors["user"][0]) #这样可以取出具体的错误,然后返回给模板通过{{ form.errors.user.0 }}显示出来

渲染标签

form除了做校验用还可以做标签用(先拿到一个未绑定数据的form),生成的每个input标签就是form类中字段的名字
views:

class UserForm(forms.Form):
    user = forms.CharField(       
        label="用户名",   #自定义form表单显示到网页的名字
        min_length=5,
        error_messages={"required": "不能为空", "min_length": "最小长度不能小于5"},  #自定义错误提示信息
        widget=widgets.TextInput(attrs={"class":"form-clontrol"})  #自定义属性,添加一个Bootstrap样式
    )

    tel=forms.CharField(label="手机号", max_length=8, widget=widgets.TextInput(attrs={"class": "form-control"}))
    email=forms.EmailField(label="邮箱", widget=widgets.TextInput(attrs={"class": "form-control"}))

Widgets

每个表单字段都有一个对应的Widget 类,它对应一个HTML 表单Widget,例如<input type="text">。

在大部分情况下,字段都具有一个合理的默认Widget。例如,默认情况下,CharField 具有一个TextInput Widget,它在HTML 中生成一个<input type="text">

表单渲染的选项

对于<label>/<input> 对,还有几个输出选项:

{{ form.as_table }} 以表格的形式将它们渲染在<tr> 标签中
{{ form.as_p }} 将它们渲染在<p> 标签中
{{ form.as_ul }} 将它们渲染在<li> 标签中
注意,你必须自己提供<table> 或<ul> 元素。

模板:

{#方案1#}

{#<form action="" method="post" novalidate>#}
{#    {% csrf_token %}#}
{#    {{ form.as_p }}#}
{##}
{#    <input type="submit">#}
{#</form>#}

{#方案2#}

{#<form action="" method="post" novalidate>#}
{#    {% csrf_token %}#}
{#    <div>#}
{#        用户名#}
{#        {{ form.user }}#}
{#    </div>#}
{##}
{#    <div>#}
{#        邮箱#}
{#        {{ form.email }}#}
{#    </div>#}
{#      <div>#}
{#        手机号#}
{#        {{ form.tel }}#}
{#    </div>#}
{#    #}
{#    <input type="submit">#}
{#</form>#}

方案3

<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form action="" method="post" novalidate>
                {% csrf_token %}
                {% for filed in form %}
                <div>
                    <label for="">{{ filed.label }}</label>
                    {{ filed }}
                </div>
                {% endfor %}
                <input type="submit">
            </form>
        </div>
    </div>
</div>
</body>
</html>

更多内容:http://www.cnblogs.com/yuanchenqi/articles/7614921.html

用户认证基于session,
用户信息存储在auth_user表中,
在命令行新建超级用户:(manage.py)
createsuperuser

用户登录

def login(request):

    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")

        #校验,将获取到的用户名和密码与auth_user表中的记录做比对,此时会将password转换成加密信息再比对
        user = auth.authenticate(username=user, password=pwd) 
        #如果比对成功会返回一个User对象,失败user会得到一个None

        if user:
            #可以获得一个request.user对象,这个对象可以取到当前user对象所代表的用户的所有信息
            auth.login(request, user)
            #此函数使用django的session框架给某个已认证的用户附加上session id等信息。

            return redirect("/index/")  
        else:
            return redirect("/login/")

    return render(request, "login.html")

状态保存验证

def index(request):
    if not request.user:
        return redirect("/login/")

    #使用request.user获取用户名
    name = request.user.username
    return render(request, "index.html", {"name":name})

## 注销
def logout(request):
    #这句话的本质还是调用request.session.flush()
    auth.logout(request)
    #当调用该函数时,当前请求的session信息会全部清除

    return redirect("/login/")

注册(创建用户)

def reg(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")

        #create_user创建一个普通用户,
        User.objects.create_user(username=user, password=pwd)
        return redirect("/login/")

    return render(request, "reg.html")

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python Day18 Django

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python Day18 Django

(1)获取cookie request.COOKIE(2)设置cookieresponse.set_cookie("","",)(3)cookie参数def set_cookie(self, key, value='', max_age=N
2023-01-31

python摸爬滚打之day18----

1、issubclass(a,b)  ----> 判断a是否是b的子类.   isinstance(a,b)  ----> 判断a这个对象是否是b类型的(可以向上判断, 即考虑继承关系往父类判断)   type(a)  ----> 获取到a
2023-01-30

python+django

经过一段时间学习,用python+django写了个简单的web管理系统,第一次做这东西,水平很次还有待提高! 登录界面 每个用户用到的基本选项(可以记录登陆后的操作和一些事项,同组用户可以查看;可以修改自己用户资料;) 添加删除组(系统采
2023-01-31

Python-Django

准备工作新建一个Django项目# 新建一个django项目$ django-admin startproject mysite# 新建一个app$ django-admin startapp blog项目的结构├── blog│   ├─
2023-01-31

python-django-apache

今天弄了一天django,想把它架到apache上这是apache的conf配置文件中我加入的内容Listen 127.0.0.1:8888        
2023-01-31

Python Day16 Django

创建一个django projectdjango-admin startproject 项目名在项目名目录下创建应用python manage.py startapp blog在project/settings.py中加入appINSTAL
2023-01-31

ubuntu+Django+python

众所周知,Django中如果使用的是python3,其官方默认使用的mysqldb是不能用的,原因:额,就是还没开发出来呗。然而,天无绝人之路,我们还可以使用mysqlclient连接mysql,今天我们来聊聊怎么从零开始使用mysqlcl
2023-01-31

python django - stat

static文件相关操作涉及:a. 文件位置与访问路径映射b. setting.py与static相关配置STATIC_URLSTATIC_ROOTSTATICFILES_DIRS c. html中对于static文件引用方式d. pyt
2023-01-31

Python基础(Django)

介绍Django之前,先来明确几个基础概念:1、什么是Web框架?    Web框架其实是建立web应用的一种方式,它为应用程序提供一套程序框架,这样开发者可以专注于编写清晰、易维护的代码,而无需从头做起。    他们基本上都以相同的方式工
2023-01-31

python+django+mysql学

安装python1. 从 http://www.python.org/download/ 下载最新的python版本 (我用的是python2.72, 当时最稳定的)2. 然后一路next, 安装到你想要的目录下3. 然后更改path,
2023-01-31

python+django的安装

找来找去,终于找到一种适合自己的web开发了!不过是否真的适合自己,那就不大清楚了!但是不做永远就不知道什么是web开发了。废话少说,开始不知道什么是尽头的web之旅吧。首先就是安装了,python的安装很简单,上官网下载安装包,然后双击就
2023-01-31

python 终级篇 django --

一般操作                                                         必会的13条             <1> all(): 查询所有结果<2> get
2023-01-30

python django系列(三)

数据库,里面有各种宝贝,一个没有数据库的网站,提供的功能非常有限连接数据库mysql是最常用的数据库,这里将django和mysql连接。安装:easy_install MySQL-python 或pip install MySQL-py
2023-01-31

python-django 模型mode

Django通过model不可以创建数据库,但可以创建数据库表,一下是创建表的字段以及表字段的参数。一、字段1、models.AutoField  自增列 = int(11)  如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自
2023-01-31

IIS 部署 Python Django

知道的,百度上搜出来的东西质量令人唏嘘。当你求助的时候多半还得靠自己,或者靠Google介入正题,详细来一遍流程吧当然,我是用Visual Studio 2019 来编辑开发Django项目的,如果你也是那么巧了。这可以帮你如果你Djang
2023-01-30

python-Django里CSRF 对

CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的×××方式。    我的理解是,比如你访问过招商银行的网站并登陆之后,你的cookie信息暂时不会失效,    这时,hacker通过各种方式诱导
2023-01-31

【Python】重置Django Mig

# 方式一# find . -path "*/migrationsmigrations/*.pyc" -delete# pyth
2023-01-31

python终极篇 ---django

模板系统                                                1. MVC和MTV框架 1. MVC M: model 模型 对
2023-01-30

python终极篇 --- django

周末没事自己写了个班级管理系统,虽然简单,但也算个前期学习的总结吧from django.db import models# Create your models here.class Banji(models.Model): gra
2023-01-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录