Django 基础篇

Django 基础篇

 

一、什么是框架?

框架呢就是指:为解决一个开放性问题而设计的具有一定约束性的支撑结构。对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

 

二、自定义web框架

通过python标准库提供的wsgiref模块开发一个自己的Web框架。

#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server

def index():
    return 'index'

def login():
    return 'login'

def routers():
    
    urlpatterns = (
        ('/index/',index),
        ('/login/',login),
    )
    
    return urlpatterns

def RunServer(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    url = environ['PATH_INFO']
    urlpatterns = routers()
    func = None
    for item in urlpatterns:
        if item[0] == url:
            func = item[1]
            break 
    if func:
        return func()
    else:
        return '404 not found'
    
if __name__ == '__main__':
    httpd = make_server('', 8000, RunServer)
    print "Serving HTTP on port 8000..."
    httpd.serve_forever()
自定义web框架

三、MTV和MVC模式

1.MVC就是把web应用分为模型(M),控制器(C),视图(V)三层;他们之间以一种插件似的,松耦合的方式连接在一起。

2..Django的MTV模式本质上与MVC模式没有什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同,Django的MTV分别代表:

       Model(模型):负责业务对象与数据库的对象(ORM)

       Template(模版):负责如何把页面展示给用户

       View(视图):负责业务逻辑,并在适当的时候调用Model和Template

3.让我们用图来看一下完整的web请求执行的过程:

 

 

四、Django基础知识:

4.1 创建Django项目过程中常用的一些命令:

1、终端:django-admin startproject sitename(创建一个项目)

2、 python manage.py runserver 0.0.0.0 (启动一个应用程序)
  python manage.py startapp appname (创建一个应用程序)
  python manage.py syncdb
  python manage.py makemigrations (创建数据库表单)
  python manage.py migrate(创建数据库)

       python manage.py fiush (清空数据库)

 

4.2Django项目的配置文:

4.2.1 数据库文件配置:

 1 1    django默认支持sqlite,mysql, oracle,postgresql数据库。
 2 
 3      <1> sqlite
 4 
 5             django默认使用sqlite的数据库,默认自带sqlite的数据库驱动 , 引擎名称:django.db.backends.sqlite3
 6 
 7      <2> mysql
 8 
 9             引擎名称:django.db.backends.mysql
10 
11 2    mysql驱动程序
12 
13    MySQLdb(mysql python)
14    mysqlclient
15    MySQL
16    PyMySQL(纯python的mysql驱动程序)
17 
18 3.DATABASES = {
19 
20     'default': {
21 
22         'ENGINE': 'django.db.backends.mysql', 
23 
24         'NAME': 'books',    #你的数据库名称
25 
26         'USER': 'root',   #你的数据库用户名
27 
28         'PASSWORD': '', #你的数据库密码
29 
30         'HOST': '', #你的数据库主机,留空默认为localhost
31 
32         'PORT': '3306', #你的数据库端口
33 
34     }
35 
36 }
37 
38 
39 4.NAME即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建
40 
41 USER和PASSWORD分别是数据库的用户名和密码。
42 
43 设置完后,再启动我们的Django项目前,我们需要激活我们的mysql。
44 
45 然后,启动项目,会报错:no module named MySQLdb
46 
47 这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb对于py3有很大问题,所以我们需要的驱动是PyMySQL
48 
49 所以,我们只需要找到项目名文件下的__init__,在里面写入:
50 
51 import pymysql
52 pymysql.install_as_MySQLdb()

4.2.2 模板和静态文件的简单配置:

TEMPLATE_DIRS = (
        os.path.join(BASE_DIR,'templates'),
    )


STATICFILES_DIRS = (
        os.path.join(BASE_DIR,'static'),
    )  # 建立文件夹名称和在html文件中引用js等都用这个名字。保持三者一致

4.2.3其余文件配置详解:

一、概述:

     #静态文件交由Web服务器处理,Django本身不处理静态文件。简单的处理逻辑如下(以nginx为例):

     #          URI请求-----> 按照Web服务器里面的配置规则先处理,以nginx为例,主要求配置在nginx.
                             #conf里的location

                         |---------->如果是静态文件,则由nginx直接处理

                         |---------->如果不是则交由Django处理,Django根据urls.py里面的规则进行匹配

    # 以上是部署到Web服务器后的处理方式,为了便于开发,Django提供了在开发环境的对静态文件的处理机制,方法是这样:

    #1、在INSTALLED_APPS里面加入'django.contrib.staticfiles',

    #2、在urls.py里面加入
       if settings.DEBUG:  
           urlpatterns += patterns('', url(r'^media/(?P<path>.*)$', 
           'django.views.static.serve', {'document_root': settings.MEDIA_ROOT }),   
            url(r'^static/(?P<path>.*)$',
          'django.views.static.serve',{'document_root':settings.STATIC_ROOT}), )  

    # 3、这样就可以在开发阶段直接使用静态文件了。

二、MEDIA_ROOT和MEDIA_URL

        #而静态文件的处理又包括STATIC和MEDIA两类,这往往容易混淆,在Django里面是这样定义的:

        #MEDIA:指用户上传的文件,比如在Model里面的FileFIeld,ImageField上传的文件。如果你定义

        #MEDIA_ROOT=c:\temp\media,那么File=models.FileField(upload_to="abc/")#,上传的文件就会被保存到c:\temp\media\abc  
        #eg:
            class blog(models.Model):  
                   Title=models.charField(max_length=64)  
                   Photo=models.ImageField(upload_to="photo") 
        #     上传的图片就上传到c:\temp\media\photo,而在模板中要显示该文件,则在这样写
        #在settings里面设置的MEDIA_ROOT必须是本地路径的绝对路径,一般是这样写:
                 BASE_DIR= os.path.abspath(os.path.dirname(__file__))  
                 MEDIA_ROOT=os.path.join(BASE_DIR,'media/').replace('\\','/') 

        #MEDIA_URL是指从浏览器访问时的地址前缀,举个例子:
            MEDIA_ROOT=c:\temp\media\photo  
            MEDIA_URL="/data/"
        #在开发阶段,media的处理由django处理:

        #    访问http://localhost/data/abc/a.png就是访问c:\temp\media\photo\abc\a.png

        #    在模板里面这样写<img src="{{MEDIA_URL}}abc/a.png">

        #    在部署阶段最大的不同在于你必须让web服务器来处理media文件,因此你必须在web服务器中配置,
        #  以便能让web服务器能访问media文件
        #    以nginx为例,可以在nginx.conf里面这样:

                 location ~/media/{
                       root/temp/
                       break;
                    }

        #    具体可以参考如何在nginx部署django的资料。

三、STATIC_ROOT和STATIC_URL、
    STATIC主要指的是如css,js,images这样文件,在settings里面可以配置STATIC_ROOT和STATIC_URL,
    配置方式与MEDIA_ROOT是一样的,但是要注意

    #STATIC文件一般保存在以下位置:

    #1、STATIC_ROOT:在settings里面设置,一般用来放一些公共的js,css,images等。

    #2、app的static文件夹,在每个app所在文夹均可以建立一个static文件夹,然后当运行collectstatic时,
    #    Django会遍历INSTALL_APPS里面所有app的static文件夹,将里面所有的文件复制到STATIC_ROOT。因此,
    #   如果你要建立可复用的app,那么你要将该app所需要的静态文件放在static文件夹中。

    # 也就是说一个项目引用了很多app,那么这个项目所需要的css,images等静态文件是分散在各个app的static文件的,比
    #  较典型的是admin应用。当你要发布时,需要将这些分散的static文件收集到一个地方就是STATIC_ROOT。

    #3、STATIC文件还可以配置STATICFILES_DIRS,指定额外的静态文件存储位置。
    #  STATIC_URL的含义与MEDIA_URL类似。

    # ----------------------------------------------------------------------------
    #注意1:
        #为了后端的更改不会影响前端的引入,避免造成前端大量修改

        STATIC_URL = '/static/'               #引用名
        STATICFILES_DIRS = (
            os.path.join(BASE_DIR,"statics")  #实际名 ,即实际文件夹的名字
        )

        #django对引用名和实际名进行映射,引用时,只能按照引用名来,不能按实际名去找
        #<script src="/statics/jquery-3.1.1.js"></script>
        #------error-----不能直接用,必须用STATIC_URL = '/static/':
        #<script src="/static/jquery-3.1.1.js"></script>

    #注意2(statics文件夹写在不同的app下,静态文件的调用):

        STATIC_URL = '/static/'

        STATICFILES_DIRS=(
            ('hello',os.path.join(BASE_DIR,"app01","statics")) ,
        )

        #<script src="/static/hello/jquery-1.8.2.min.js"></script>

    #注意3:
        STATIC_URL = '/static/'
        {% load staticfiles %}
       # <script src={% static "jquery-1.8.2.min.js" %}></script>
配置详解

4.3 路由系统:

1、每个路由规则对应一个view中的函数:

url(r'^index/(\d*)', views.index),

# 正则表达式中还有分组,这样可以把参数传递到后台的视图函数,有专门的接受参数的地方
url(r'^manage/(?P<name>\w*)/(?P<id>\d*)', views.manage),
# 对接受参数的参数名称进行了限制,必须为<>内的名字
url(r'^manage/(?P<name>\w*)', views.manage,{'id':333})

2、根据app对路由规则进行一次分类:

url(r'^web/',include('web.urls')),

django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。

4.4 模板

4.4.1、模版的执行

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

4.4.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" %} #要写在HTML的最头顶
         {% block title %}{% endblock %}
    • 帮助方法:
      {{ item.event_start|date:"Y-m-d H:i:s"}}
      {{ bio|truncatewords:"30" }}
      {{ my_list|first|upper }}
      {{ name|lower }}

    

        通过simple_tag实现模版语言中的帮助方法

           a、在app中创建templatetags文件夹

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

 1 #!/usr/bin/env python
 2 #coding:utf-8
 3 
 4 from django import template
 5 from django.utils.safestring import mark_safe
 6 from django.template.base import resolve_variable, Node, TemplateSyntaxError
 7  
 8 register = template.Library()
 9  
10 @register.simple_tag
11 def my_simple_time(v1,v2,v3):
12     return  v1 + v2 + v3
13  
14 @register.simple_tag
15 def my_input(id,arg):
16     result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
17     return mark_safe(result)

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

{% load xxx %}

        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',
)

4.5 视图函数

4.5.1

http请求中产生两个核心对象:

        http请求:HttpRequest对象

        http响应:HttpResponse对象

所在位置:django.http

之前我们用到的参数request就是HttpRequest    检测方法:isinstance(request,HttpRequest)

1 HttpRequest对象的属性和方法:

 1 # path:       请求页面的全路径,不包括域名
 2 #
 3 # method:     请求中使用的HTTP方法的字符串表示。全大写表示。例如
 4 #
 5 #                    if  req.method=="GET":
 6 #
 7 #                              do_something()
 8 #
 9 #                    elseif req.method=="POST":
10 #
11 #                              do_something_else()
12 #
13 # GET:         包含所有HTTP GET参数的类字典对象
14 #
15 # POST:       包含所有HTTP POST参数的类字典对象
16 #
17 #              服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
18 #              HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
19 #              if req.POST来判断是否使用了HTTP POST 方法;应该使用  if req.method=="POST"
20 #
21 #
22 #
23 # COOKIES:     包含所有cookies的标准Python字典对象;keys和values都是字符串。
24 #
25 # FILES:      包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中                     name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
26 #
27 #             filename:      上传文件名,用字符串表示
28 #             content_type:   上传文件的Content Type
29 #             content:       上传文件的原始内容
30 #
31 #
32 # user:       是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
33 #              没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
34 #              可以通过user的is_authenticated()方法来辨别用户是否登陆:
35 #              if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
36 #              时该属性才可用
37 #
38 # session:    唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。
39 
40 #方法
41 get_full_path(),   比如:http://127.0.0.1:8000/index33/?name=123 ,req.get_full_path()得到的结果就是/index33/?name=123
42 req.path:/index33
HttpRequest请求

注意一个常用方法:request.POST.getlist('')

2 HttpResponse对象:

  对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse对象。

  HttpResponse类在django.http.HttpResponse

  在HttpResponse对象上扩展的常用方法:

页面渲染:         render()(推荐)
                 render_to_response(),
页面跳转:         redirect("路径")
locals():    可以直接将函数中所有的变量传给模板

注意:

总结: render和redirect的区别:
     1 if render的页面需要模板语言渲染,需要的将数据库的数据加载到html,那么所有的这一部分
除了写在yuan_back的视图函数中,必须还要写在login中,代码重复,没有解耦.

     2 the most important: url没有跳转到/yuan_back/,而是还在/login/,所以当刷新后
又得重新登录.



4.6、Model(模型)

    涉及到数据库相关的操作的时候一般会这样操作:

  • 创建数据库,设计表结构和字段
  • 使用 MySQLdb(pymysql) 来连接数据库,并编写数据访问层代码
  • 业务逻辑层去调用数据访问层执行数据库操作

 

 

mport MySQLdb
 
def GetList(sql):
    db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost')
    cursor = db.cursor()
    cursor.execute(sql)
    data = cursor.fetchall()
    db.close()
    return data
 
def GetSingle(sql):
    db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost')
    cursor = db.cursor()
    cursor.execute(sql)
    data = cursor.fetchone()
    db.close()
    return data
MysqL操作

 

django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表。

1、创建Model,之后可以根据Model来创建数据库表:

1 from django.db import models
2  
3 class userinfo(models.Model):
4     name = models.CharField(max_length=30)
5     email = models.EmailField()
6     mode = models.TextField()

字段详解:

1、models.AutoField  自增列 = int(11)
  如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
2、models.CharField  字符串字段
  必须 max_length 参数
3、models.BooleanField  布尔类型=tinyint(1)
  不能为空,Blank=True
4、models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
  继承CharField,所以必须 max_lenght 参数
5、models.DateField  日期类型 date
  对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
6、models.DateTimeField  日期类型 datetime
  同DateField的参数
7、models.Decimal  十进制小数类型 = decimal
  必须指定整数位max_digits和小数位decimal_places
8、models.EmailField  字符串类型(正则表达式邮箱) =varchar
  对字符串进行正则表达式
9、models.FloatField  浮点类型 = double
10、models.IntegerField  整形
11、models.BigIntegerField  长整形
  integer_field_ranges = {
    'SmallIntegerField': (-32768, 32767),
    'IntegerField': (-2147483648, 2147483647),
    'BigIntegerField': (-9223372036854775808, 9223372036854775807),
    'PositiveSmallIntegerField': (0, 32767),
    'PositiveIntegerField': (0, 2147483647),
  }
12、models.IPAddressField  字符串类型(ip4正则表达式)
13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)
  参数protocol可以是:both、ipv4、ipv6
  验证时,会根据设置报错
14、models.NullBooleanField  允许为空的布尔类型
15、models.PositiveIntegerFiel  正Integer
16、models.PositiveSmallIntegerField  正smallInteger
17、models.SlugField  减号、下划线、字母、数字
18、models.SmallIntegerField  数字
  数据库中的字段有:tinyint、smallint、int、bigint
19、models.TextField  字符串=longtext
20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
21、models.URLField  字符串,地址正则表达式
22、models.BinaryField  二进制<br>23、models.ImageField   图片<br>24、models.FilePathField 文件
字段详解
1、null=True
  数据库中字段是否可以为空
2、blank=True
  django的 Admin 中添加数据时是否可允许空值
3、primary_key = False
  主键,对AutoField设置主键后,就会代替原来的自增 id 列
4、auto_now 和 auto_now_add
  auto_now   自动创建---无论添加或修改,都是当前操作的时间
  auto_now_add  自动创建---永远是创建时的时间
5、choices
GENDER_CHOICE = (
        (u'M', u'Male'),
        (u'F', u'Female'),
    )
gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
6、max_length
7、default  默认值
8、verbose_name  Admin中字段的显示名称
9、name|db_column  数据库中的字段名称
10、unique=True  不允许重复
11、db_index = True  数据库索引
12、editable=True  在Admin里是否可编辑
13、error_messages=None  错误提示
14、auto_created=False  自动创建
15、help_text  在Admin中提示帮助信息
16、validators=[]
17、upload-to
more 字段

数据库中表与表之间的关系:

  • 一对多,models.ForeignKey(ColorDic)
  • 一对一,models.OneToOneField(OneModel)
  • 多对多,authors = models.ManyToManyField(Author)

应用场景:

    • 一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了)。
      例如:原有含10列数据的一张表保存相关信息,经过一段时间之后,10列无法满足需求,需要为原来的表再添加5列数据。
    • 一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)。
      例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。
    • 多对多:在某表中创建一行数据是,有一个可以多选的下拉框。
      例如:创建用户信息,需要为用户指定多个爱好。

 

2、数据库操作

    • 增加:创建实例,并调用save
    • 更新:a.获取实例,再sava;b.update(指定列)
    • 删除:a. filter().delete(); b.all().delete()
    • 获取:a. 单个=get(id=1) ;b. 所有 = all()
    • 过滤:filter(name='xxx');filter(name__contains='');(id__in = [1,2,3]) ;
      icontains(大小写无关的LIKE),startswith和endswith, 还有range(SQLBETWEEN查询)'gt', 'in', 'isnull', 'endswith', 'contains', 'lt', 'startswith', 'iendswith', 'icontains','range', 'istartswith'
    • 排序:order_by("name") =asc ;order_by("-name")=desc
    • 返回第n-m条:第n条[0];前两条[0:2]
    • 指定映射:values
    • 数量:count()
    • 聚合:from django.db.models import Min,Max,Sum objects.all().aggregate(Max('guest_id'))
    • 原始SQL
cursor = connection.cursor()
cursor.execute('''SELECT DISTINCT first_name ROM people_person WHERE last_name = %s""", ['Lennon'])
row = cursor.fetchone() 

4.7.Form

django中的Form一般有两种功能:

  • 输入html
  • 验证用户输入
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
from django import forms
from django.core.exceptions import ValidationError


def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误')


class PublishForm(forms.Form):

    user_type_choice = (
        (0, u'普通用户'),
        (1, u'高级用户'),
    )

    user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,
                                                                  attrs={'class': "form-control"}))

    title = forms.CharField(max_length=20,
                            min_length=5,
                            error_messages={'required': u'标题不能为空',
                                            'min_length': u'标题最少为5个字符',
                                            'max_length': u'标题最多为20个字符'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'标题5-20个字符'}))

    memo = forms.CharField(required=False,
                           max_length=256,
                           widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'详细描述', 'rows': 3}))

    phone = forms.CharField(validators=[mobile_validate, ],
                            error_messages={'required': u'手机不能为空'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'手机号码'}))

    email = forms.EmailField(required=False,
                            error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'},
                            widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'}))


Form

Form
form

4.8 分页

分页时需要做三件事:

  • 创建处理分页数据的类
  • 根据分页数据获取数据
  • 输出分页HTML,即:[上一页][1][2][3][4][5][下一页]
 1 #!/usr/bin/env python
 2 # _*_coding:utf-8_*_
 3 from django.utils.safestring import mark_safe
 4  
 5 class PageInfo(object):
 6     def __init__(self,current,totalItem,peritems=5):
 7         self.__current=current
 8         self.__peritems=peritems
 9         self.__totalItem=totalItem
10     def From(self):
11         return (self.__current-1)*self.__peritems
12     def To(self):
13         return self.__current*self.__peritems
14     def TotalPage(self):  #总页数
15         result=divmod(self.__totalItem,self.__peritems)
16         if result[1]==0:
17             return result[0]
18         else:
19             return result[0]+1
20  
21 def Custompager(baseurl,currentPage,totalpage):  #基础页,当前页,总页数
22     perPager=11
23     #总页数<11
24     #0 -- totalpage
25     #总页数>11
26         #当前页大于5 currentPage-5 -- currentPage+5
27             #currentPage+5是否超过总页数,超过总页数,end就是总页数
28         #当前页小于5 0 -- 11
29     begin=0
30     end=0
31     if totalpage <= 11:
32         begin=0
33         end=totalpage
34     else:
35         if currentPage>5:
36             begin=currentPage-5
37             end=currentPage+5
38             if end > totalpage:
39                 end=totalpage
40         else:
41             begin=0
42             end=11
43     pager_list=[]
44     if currentPage<=1:
45         first="<a href=''>首页</a>"
46     else:
47         first="<a href='%s%d'>首页</a>" % (baseurl,1)
48     pager_list.append(first)
49  
50     if currentPage<=1:
51         prev="<a href=''>上一页</a>"
52     else:
53         prev="<a href='%s%d'>上一页</a>" % (baseurl,currentPage-1)
54     pager_list.append(prev)
55  
56     for i in range(begin+1,end+1):
57         if i == currentPage:
58             temp="<a href='%s%d' class='selected'>%d</a>" % (baseurl,i,i)
59         else:
60             temp="<a href='%s%d'>%d</a>" % (baseurl,i,i)
61         pager_list.append(temp)
62     if currentPage>=totalpage:
63         next="<a href='#'>下一页</a>"
64     else:
65         next="<a href='%s%d'>下一页</a>" % (baseurl,currentPage+1)
66     pager_list.append(next)
67     if currentPage>=totalpage:
68         last="<a href=''>末页</a>"
69     else:
70         last="<a href='%s%d'>末页</a>" % (baseurl,totalpage)
71     pager_list.append(last)
72     result=''.join(pager_list)
73     return mark_safe(result)   #把字符串转成html语言

4.9 cookie 和Session 的操作

操作Cookie

  获取cookie:request.COOKIES[key]

  设置cookie:response.set_cookie(key,value)

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

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

操作Session

  获取session:request.session[key]

  设置session:reqeust.session[key] = value

  删除session:del request[key]

1 request.session.set_expiry(value)
2 * 如果value是个整数,session会在些秒数后失效。
3 * 如果value是个datatime或timedelta,session就会在这个时间后失效。
4 * 如果value是0,用户关闭浏览器session就会失效。
5 * 如果value是None,session会依赖全局session失效策略。

简单应用:

def login(func):
    def wrap(request, *args, **kwargs):
        # 如果未登陆,跳转到指定页面
        if request.path == '/test/':
            return redirect('http://www.baidu.com')
        return func(request, *args, **kwargs)
    return wrap

 

   

 

posted @ 2017-06-20 10:18  还是牛  阅读(113)  评论(0编辑  收藏  举报