python第二十天-----Django补充

学习python已经20天了啊,从一个不萌萌哒的战5渣升级到了一个萌萌哒的战5渣

1.分页(这是一个很通用的模块,不论在任何框架里都可以使用哦)

 1 class Page(object):
 2     def __init__(self, current_page):
 3         """
 4         
 5         :param current_page: 当前的页码
 6         """
 7         self.current_page = int(current_page)
 8 
 9     @property
10     def start(self):
11         """
12         
13         :return: 返回页码展示的起始页码
14         """
15         return (self.current_page-1)*10
16 
17     @property
18     def end(self):
19         """
20         
21         :return: 返回页码展示的结束页码
22         """
23         return self.current_page*10
24 
25     def page_str(self, all_item, base_url):
26         """
27         页码展示的具体验证方法
28         :param all_item: 数据库内所有数据的条数
29         :param base_url: 基础url,因为是通用的的,所以要传递不同的url
30         :return: 
31         """
32         all_page, div = divmod(all_item, 10)    # 按每页10条展示
33         if div > 0:
34             all_page += 1
35         page_list = []
36         if all_page <= 11:                      # 当总页码少于11个时,直接展示1-最后页码
37             start = 1
38             end = all_page
39         else:
40             if self.current_page <= 6:          # 如果当前点击页码小于6,则还是展示1-11页
41                 start = 1
42                 end = 12
43             else:
44                 start = self.current_page-5     # 以当前点击页码为中心显示前5个跟后5个页码
45                 end = self.current_page+6
46                 if self.current_page+6 > all_page:
47                     start = all_page-11
48                     end = all_page
49         for i in range(start, end):
50             if i == self.current_page:
51                 temp = '<a href="%s%d" style="color:red;font-size:18px">%d</a>' % (base_url, i, i)
52             else:
53                 temp = '<a href="%s%d">%d</a>' % (base_url, i, i)
54             page_list.append(temp)
55         if self.current_page > 1:
56             pre_page = '<a href="%s%d">上一页</a>' % (base_url, self.current_page-1)
57         else:
58             pre_page = '<a href="javascript:void(0)">上一页</a>'
59         if self.current_page < all_page:
60             next_page = '<a href="%s%d">下一页</a>' % (base_url, self.current_page+1)
61         else:
62             next_page = '<a href="javascript:void(0)">下一页</a>'
63         page_list.append(next_page)
64         page_list.insert(0, pre_page)
65         first_page = '<a href="%s1">首页</a>' % base_url
66         last_page = '<a href="%s%d">末页</a>' % (base_url, all_page)
67         page_list.append(last_page)
68         page_list.insert(0, first_page)
69         page_str = ''.join(page_list)
70         return page_str

xss安全只需要在前端接收后面加‘XXXX|safe‘’即可

2.中间件(运维角度:在用户提交请求后到服务器处理该请求之前所经历的一切都可以称之为中间件)

在django中只需要记住这种那个图即可:

自定义中间件后需要在setting中注册即可使用:

 1 MIDDLEWARE= [
 2     # 'md.bfmq.M1',
 3     # 'md.bfmq.M2',
 4     'django.middleware.security.SecurityMiddleware',
 5     'django.contrib.sessions.middleware.SessionMiddleware',
 6     'django.middleware.common.CommonMiddleware',
 7     # 'django.md.csrf.CsrfViewMiddleware',
 8     'django.contrib.auth.middleware.AuthenticationMiddleware',
 9     'django.contrib.messages.middleware.MessageMiddleware',
10     'django.middleware.clickjacking.XFrameOptionsMiddleware',
11 ]

需要注意的问题是现在有一些版本问题,自定义的中间件需要继承一个类:

 1 #!/usr/bin/env python
 2 from django.utils import deprecation
 3 
 4 
 5 class M1(deprecation.MiddlewareMixin):
 6     def process_request(self, request):
 7         print('M1.request')
 8 
 9     def process_response(self, request, response):
10         print('M1.response')
11         return response

3.信号(就是满足触发条件时执行些什么)

内置信号
Model signals pre_init # django的modal执行其构造方法前,自动触发 post_init # django的modal执行其构造方法后,自动触发 pre_save # django的modal对象保存前,自动触发 post_save # django的modal对象保存后,自动触发 pre_delete # django的modal对象删除前,自动触发 post_delete # django的modal对象删除后,自动触发 m2m_changed # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发 class_prepared # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发 Management signals pre_migrate # 执行migrate命令前,自动触发 post_migrate # 执行migrate命令后,自动触发 Request/response signals request_started # 请求到来前,自动触发 request_finished # 请求结束后,自动触发 got_request_exception # 请求异常后,自动触发 Test signals setting_changed # 使用test测试修改配置文件时,自动触发 template_rendered # 使用test测试渲染模板时,自动触发 Database Wrappers connection_created # 创建数据库连接时,自动触发

 

 1 from django.core.signals import request_finished
 2     from django.core.signals import request_started
 3     from django.core.signals import got_request_exception
 4 
 5     from django.db.models.signals import class_prepared
 6     from django.db.models.signals import pre_init, post_init
 7     from django.db.models.signals import pre_save, post_save
 8     from django.db.models.signals import pre_delete, post_delete
 9     from django.db.models.signals import m2m_changed
10     from django.db.models.signals import pre_migrate, post_migrate
11 
12     from django.test.signals import setting_changed
13     from django.test.signals import template_rendered
14 
15     from django.db.backends.signals import connection_created
16 
17 
18     def callback(sender, **kwargs):
19         print("bfmq_callback")
20         print(sender,kwargs)
21 
22     bfmq.connect(callback)
23     # bfmq指上述导入的内容

4.缓存

a.调试(无任何操作,只是练习时用)

 1 # 此为开始调试用,实际内部不做任何操作
 2     # 配置:
 3         CACHES = {
 4             'default': {
 5                 'BACKEND': 'django.core.cache.backends.dummy.DummyCache',     # 引擎
 6                 'TIMEOUT': 300,                                               # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
 7                 'OPTIONS':{
 8                     'MAX_ENTRIES': 300,                                       # 最大缓存个数(默认300)
 9                     'CULL_FREQUENCY': 3,                                      # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
10                 },
11                 'KEY_PREFIX': '',                                             # 缓存key的前缀(默认空)
12                 'VERSION': 1,                                                 # 缓存key的版本(默认1)
13                 'KEY_FUNCTION' 函数名                                          # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
14             }
15         }
16 
17 
18     # 自定义key
19     def default_key_func(key, key_prefix, version):
20         """
21         Default function to generate keys.
22 
23         Constructs the key used by all other methods. By default it prepends
24         the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
25         function with custom key making behavior.
26         """
27         return '%s:%s:%s' % (key_prefix, version, key)
28 
29     def get_key_func(key_func):
30         """
31         Function to decide which key function to use.
32 
33         Defaults to ``default_key_func``.
34         """
35         if key_func is not None:
36             if callable(key_func):
37                 return key_func
38             else:
39                 return import_string(key_func)
40         return default_key_func

b.内存

1 # 此缓存将内容保存至内存的变量中
2     # 配置:
3         CACHES = {
4             'default': {
5                 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
6                 'LOCATION': 'unique-snowflake',
7             }
8         }

c.文件

1 # 此缓存将内容保存至文件
2     # 配置:
3 
4         CACHES = {
5             'default': {
6                 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
7                 'LOCATION': '/var/tmp/django_cache',
8             }
9         }

d.数据库

 1 # 此缓存将内容保存至数据库
 2 
 3     # 配置:
 4         CACHES = {
 5             'default': {
 6                 'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
 7                 'LOCATION': 'my_cache_table', # 数据库表
 8             }
 9         }
10 
11     # 注:执行创建表命令 python manage.py createcachetable

e.Memcache缓存(python-memcached模块)

 1 # 此缓存使用python-memcached模块连接memcache
 2 
 3     CACHES = {
 4         'default': {
 5             'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
 6             'LOCATION': '127.0.0.1:11211',
 7         }
 8     }
 9 
10     CACHES = {
11         'default': {
12             'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
13             'LOCATION': 'unix:/tmp/memcached.sock',
14         }
15     }   
16 
17     CACHES = {
18         'default': {
19             'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
20             'LOCATION': [
21                 '172.19.26.240:11211',
22                 '172.19.26.242:11211',
23             ]
24         }
25     }

f.Memcache缓存(pylibmc模块)

 1 # 此缓存使用pylibmc模块连接memcache
 2     
 3     CACHES = {
 4         'default': {
 5             'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
 6             'LOCATION': '127.0.0.1:11211',
 7         }
 8     }
 9 
10     CACHES = {
11         'default': {
12             'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
13             'LOCATION': '/tmp/memcached.sock',
14         }
15     }   
16 
17     CACHES = {
18         'default': {
19             'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
20             'LOCATION': [
21                 '172.19.26.240:11211',
22                 '172.19.26.242:11211',
23             ]
24         }
25     }

g.redis需要下载第三方模块实现,ps:你们都不知道我大tair么?哈哈哈

全站进行缓存:

 1 使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存
 2 
 3     MIDDLEWARE = [
 4         'django.middleware.cache.UpdateCacheMiddleware',
 5         # 其他中间件...
 6         'django.middleware.cache.FetchFromCacheMiddleware',
 7     ]
 8 
 9     CACHE_MIDDLEWARE_ALIAS = ""
10     CACHE_MIDDLEWARE_SECONDS = ""
11     CACHE_MIDDLEWARE_KEY_PREFIX = ""

某视图进行缓存:

 1 方式一:
 2         from django.views.decorators.cache import cache_page
 3 
 4         @cache_page(60 * 15)
 5         def my_view(request):
 6             ...
 7 
 8     方式二:
 9         from django.views.decorators.cache import cache_page
10 
11         urlpatterns = [
12             url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
13         ]

html某部分缓存(缓存母板~)

1 a. 引入TemplateTag
2 
3    {% load cache %}
4 
5 b. 使用缓存
6 
7    {% cache 5000 缓存key %}
8         缓存内容
9    {% endcache %}

5.form补充

 1 class IndexForm(forms.Form):
 2     c = models.UserType.objects.all().values_list('id','caption')
 3     user_type_id = forms.IntegerField(widget=forms.Select(choices=c))
 4     
 5     def __init__(self, *args, **kwargs):
 6         """
 7         在每次url访问后函数调用类时都执行次就会获取到数据库最新数据
 8         :param args: 
 9         :param kwargs: 
10         """
11         super(IndexForm, self).__init__(*args, **kwargs)
12         self.fields['user_type_id'].widget.choices = models.UserType.objects.all().values_list('id','caption')
13 
14 
15 def index(request):
16     form = IndexForm()
17     return render(request, 'index.html', {'form': form})

 

posted @ 2016-12-26 14:52  北方姆Q  阅读(247)  评论(0编辑  收藏  举报