Python之路Day21-自定义分页和cookie

本节知识点概要

1.URL

2.views

        - 请求其他信息

        - 装饰器

3.Templates

          - 母版

           - 自定义

4.Models操作

5.分页(自定义分页)

6.cookie

7.session 

8.Form验证
  - 缓存
  - 中间件
  - 信号
  - CSRF
  - Admin/ModelForm

上节内容回顾

1.请求周期

url> 路由 > 函数或类 > 返回字符串或者模板语言?

form表单提交

提交 -> url路由系统 > 函数或类中的方法 
                 - 执行其他操作,最终返回
                 HttpResponse('....')
                 render(request,'index.html')
                 redirect('/index/')
                  返回字符串  >   > 返回给用户
(当接受到redirect时)自动发起另外一个请求
--> url   .....

 Ajax请求

$.ajax({
    url: '/index/',
    data: {'k': 'v', 'list': [1,2,3,4], 'k3': JSON.stringfy({'k1': 'v'}))}, $(form对象).serilize() 
    type: 'POST',
    dataType: 'JSON':
    traditional: true,
    success:function(d){
        location.reload()              # 刷新
        location.href = "某个地址"      # 跳转
    }
})
提交 -> url -> 函数或类中的方法 
                HttpResponse('{}')
                render(request, 'index.html', {'name': 'v1'})
                <h1>{{ name }}</h1> --> 
                <h1>v1</h1>
                
                XXXXXXX redirect...
用户    <<<<<  字符串

2.路由系统URL

a. /index/                               ->  函数或类
b. /index/(\d+)                          ->  函数或类
c. /index/(?P<nid>\d+)                   ->  函数或类
d. /index/(?P<nid>\d+) name='root'       ->  函数或类
            reverse()
            {% url 'root' 1%}
e. /crm/    include('app01.urls')        -> 路由分发
        
f. 默认值
    url(r'^index/', views.index, {'name': 'root'}),
            def index(request,name):
                print(name)
                return HttpResponse('OK')
    
g. 命名空间
       /admin/    include('app01.urls',namespace='m1')
            /crm/      include('app01.urls',namespace='m1')
            
        app01.urls
/index/ name = 'n1'
reverser('m1:n1')

3.viwes

def func(request):
    request.POST
    request.GET
    request.FILES
    request.getlist
    request.method
    request.path_info
    
    return render,HttpResponse,redirect

4.模板引擎

render(request, 'index.html')
# for
# if
# 索引.   keys  values items    all

5.medels

单表
class
User(models.Model): username = models.CharField(max_length=32) email = models.EmailField() 有验证功能 Django Admin 无验证功能: User.objects.create(username='root',email='asdfasdfasdfasdf') User.objects.filter(id=1).update(email='666')
多表:
创建数据库结构
class UserType(models.Model): name = models.CharField(max_length=32) class User(models.Model): username = models.CharField(max_length=32) email = models.EmailField() user_type = models.ForeignKey("UserType")
跨表操作: user_list
= User.objects.all() for obj user_list: obj.username,obj.email,obj.user_type_id,obj.user_type.name,obj.user_type.id //获取单个列表 user = User.objects.get(id=1) user.
//获取指定列内容 User.objects.all().values(
"username","user_type__name",) 多对多 class UserType(models.Model): name = models.CharField(max_length=32) class User(models.Model): username = models.CharField(max_length=32) email = models.EmailField() user_type = models.ForeignKey("UserType") m = models.ManyToMany('UserGroup') class UserGroup(models.Model): name = .... 操作: obj = User.objects.get(id=1) obj.m.add(2) obj.m.add(2,3) obj.m.add(*[1,2,3]) obj.m.remove(...) obj.m.clear() obj.m.set([1,2,3,4,5]) # 多个组,UserGroup对象 obj.m.all() obj.m.filter(name='CTO')

一、views 请求的其他信息

    from django.core.handlers.wsgi import WSGIRequest
    print(type(request))
    print(request.environ)
    for k,v in request.environ.items():
        print(k,v)
    print(request.environ['HTTP_USER_AGENT'])

装饰器

FBV

def auth(func):
    def inner(reqeust,*args,**kwargs):
        v = reqeust.COOKIES.get('username111')
        if not v:
            return redirect('/login/')
        return func(reqeust, *args,**kwargs)
    return inner

 

CBV

from django import views
from django.utils.decorators import method_decorator

@method_decorator(auth,name='dispatch')
class Order(views.View):

    # @method_decorator(auth)
    # def dispatch(self, request, *args, **kwargs):
    #     return super(Order,self).dispatch(request, *args, **kwargs)

    # @method_decorator(auth)
    def get(self,reqeust):
        v = reqeust.COOKIES.get('username111')
        return render(reqeust,'index.html',{'current_user': v})

    def post(self,reqeust):
        v = reqeust.COOKIES.get('username111')
        return render(reqeust,'index.html',{'current_user': v})

 

二、templates

模板继承

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %}</title>
    <link rel="stylesheet" href="/static/commons.css">
    <style>
        .pg-header{
            height: 48px;
            background-color: #1F78A4;
            color: white;
            font-size: 22px;
            line-height: 48px;

        }
    </style>
    {% block css %} {% endblock %}
</head>
<body>
    <div class="pg-header">管理系统</div>

    {% block content %} {% endblock %}

    <script src="/static/jquery.js"></script>
     {% block js %} {% endblock %}
</body>
</html>
master.html
{% extends 'master.html' %}  //指定继承模板
{% block title %}用户管理{% endblock %}
{% block content %}
        <h1>用户管理</h1>
        <ul>
            {% for i in u %}
                 <li>{{ i }}</li>
            {% endfor %}
        </ul>

    {% for i in u %}
    {% include 'tag.html' %}
    {% endfor %}

{% endblock %}

{% block css %}
    <style>
         body{
             background-color: transparent;
         }
    </style>
{% endblock %}
  {% block js %}
      <script>
      </script>
{% endblock %}

1、模版的执行

模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
View Code

 

from django import template
t = template.Template('My name is {{ name }}.')
c = template.Context({'name': 'Adrian'})
print t.render(c)
View Code
import datetime
from django import template
import DjangoDemo.settings
 
now = datetime.datetime.now()
fp = open(settings.BASE_DIR+'/templates/Home/Index.html')
t = template.Template(fp.read())
fp.close()
html = t.render(template.Context({'current_date': now}))
return HttpResponse(html
View Code
from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime
 
def current_datetime(request):
    now = datetime.datetime.now()
    t = get_template('current_datetime.html')
    html = t.render(Context({'current_date': now}))
    return HttpResponse(html)
View Code
return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))
View Code

2、模版语言

 模板中也有自己的语言,该语言可以实现数据展示

  • {{ item }}
  • {% for item in item_list %}  <a>{{ item }}</a>  {% endfor %}
      forloop.counter
      forloop.first
      forloop.last 
  • {% if ordered_warranty %}  {% else %} {% endif %}
  • 母板:{% block title %}{% endblock %}
    子板:{% extends "base.html" %}
       {% block title %}{% endblock %}
  • 帮助方法:
    {{ item.event_start|date:"Y-m-d H:i:s"}}
    {{ bio|truncatewords:"30" }}
    {{ my_list|first|upper }}
    {{ name|lower }}

3、自定义simple_tag

a、在app中创建templatetags模块

b、创建任意 .py 文件,如:xx.py

#!/usr/bin/env python
#coding:utf-8
from django import template
from django.utils.safestring import mark_safe
   
register = template.Library()
   
@register.simple_tag
def my_simple_time(v1,v2,v3):
    return  v1 + v2 + v3
 
@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

 

c、在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名

{% load xx %}

d、使用simple_tag

{% my_simple_time 1 2 3%}
{% my_input 'id_username' 'hide'%}

e、在settings中配置当前app,不然django无法找到自定义的simple_tag

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01',
)

缺点:不能作为if条件

优点:参数任意

更多见文档:https://docs.djangoproject.com/en/1.10/ref/templates/language/

4、自定义filter

a. app下创建templatetags目录
b. 任意xxoo.py文件
c. 创建template对象 register
d.

@register.filter
def func(a1,a2)
return "asdfasd"

e. settings中注册APP
f. 顶部 {% load xxoo %}
g. {{ 参数1|函数名:"参数二,参数三" }} {{ 参数1|函数名:数字 }}

缺点:最多两个参数,不能加空格
优点:能作为if条件

三、分页

前端设置为安全

{{page_str|safe }}

 后端设置为安全

    from django.utils.safestring import mark_safe
    page_str="""
            <a href="/user_list/?p=1">1</a>
            <a href="/user_list/?p=2">2</a>
            <a href="/user_list/?p=3">3</a>
    """
    page_str=mark_safe(page_str)

 范例:

__author__ = 'Administrator'
from django.utils.safestring import mark_safe


class Page:
    def __init__(self, current_page, data_count, per_page_count=10, pager_num=7):
        self.current_page = current_page
        self.data_count = data_count
        self.per_page_count = per_page_count
        self.pager_num = pager_num
    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_count
    @property
    def end(self):
        return self.current_page * self.per_page_count
    @property
    def total_count(self):
        v, y = divmod(self.data_count, self.per_page_count)
        if y:
            v += 1
        return v

    def page_str(self, base_url):
        page_list = []

        if self.total_count < self.pager_num:
            start_index = 1
            end_index = self.total_count + 1
        else:
            if self.current_page <= (self.pager_num + 1) / 2:
                start_index = 1
                end_index = self.pager_num + 1
            else:
                start_index = self.current_page - (self.pager_num - 1) / 2
                end_index = self.current_page + (self.pager_num + 1) / 2
                if (self.current_page + (self.pager_num - 1) / 2) > self.total_count:
                    end_index = self.total_count + 1
                    start_index = self.total_count - self.pager_num + 1

        if self.current_page == 1:
            prev = '<a class="page" href="javascript:void(0);">上一页</a>'
        else:
            prev = '<a class="page" href="%s?p=%s">上一页</a>' % (base_url, self.current_page - 1,)
        page_list.append(prev)

        for i in range(int(start_index), int(end_index)):
            if i == self.current_page:
                temp = '<a class="page active" href="%s?p=%s">%s</a>' % (base_url, i, i)
            else:
                temp = '<a class="page" href="%s?p=%s">%s</a>' % (base_url, i, i)
            page_list.append(temp)

        if self.current_page == self.total_count:
            nex = '<a class="page" href="javascript:void(0);">下一页</a>'
        else:
            nex = '<a class="page" href="%s?p=%s">下一页</a>' % (base_url, self.current_page + 1,)
        page_list.append(nex)

        jump = """
        <input type='text'  /><a onclick='jumpTo(this, "%s?p=");'>GO</a>
        <script>
            function jumpTo(ths,base){
                var val = ths.previousSibling.value;
                location.href = base + val;
            }
        </script>
        """ % (base_url,)
        page_list.append(jump)
        page_str = mark_safe("".join(page_list))
        return page_str
View Code
from utils import pagination
LIST=[]
for i in range(509):
    LIST.append(i)
def user_list(request):
    current_page = request.GET.get('p', 1)
    current_page = int(current_page)
    page_obj=pagination.Page(current_page,len(LIST),)
    data=LIST[page_obj.start:page_obj.end]
    page_str=page_obj.page_str("/user_list/")
    return  render(request,'user_list.html',{'li':data,'page_str':page_str})
View

 

四、cookie和session

cookie

    相当于浏览器上的一个文件

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form action="/login/" method="POST">
        <input type="text" name="username" placeholder="用户名" />
        <input type="password" name="pwd" placeholder="密码" />
        <input type="submit" />
    </form>
</body>
</html>
login
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>欢迎登录:{{ current_user }}</h1>
</body>
</html>
index

 

1、获取Cookie:

request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    参数:
        default: 默认值
           salt: 加密盐
        max_age: 后台控制过期时间

2、设置Cookie:

rep = HttpResponse(...) 或 rep = render(request, ...)
 
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',...)
    参数:
        key,              键
        value='',         值
        max_age=None,     超时时间
        expires=None,     超时时间(IE requires expires, so set it if hasn't been already.)
        path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
        domain=None,      Cookie生效的域名
        secure=False,     https传输
        httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

由于cookie保存在客户端的电脑上,所以,JavaScript和jquery也可以操作cookie。

<script src='/static/js/jquery.cookie.js'></script>
$.cookie("list_pager_num", 30,{ path: '/' });
Session

 

...

 

posted @ 2017-01-04 18:20  YoungCheung  阅读(267)  评论(0编辑  收藏  举报