笔记整理
上节内容回顾: 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. 命名空间 一级url: /admin/ include('app01.urls',namespace='m1') /crm/ include('app01.urls',namespace='m1') 二级url: app01.urls /index/ name = 'n1' 视图函数(生成url): reverser('m1:n1') 3、 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、 class User(models.Model): username = models.CharField(max_length=32) email = models.EmailField() 有验证功能 Django Admin 无验证功能:(后面通过model/modelform添加验证功能) 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") 如果是Django自动创建第三张表,manytomany这张表可放在任意一个类下面,因为它不受两张表的管理。 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') 新知识点: URL - 两个(命名空间、默认值) Views - 请求的其他信息 from django.core.handlers.wsgi import WSGIRequest request.environ 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 - 母版...html extends include - 自定义函数 simple_tag a. app下创建templatetags目录 b. 任意xxoo.py文件 c. 创建template对象 register d. @register.simple_tag def func(a1,a2,a3....) return "asdfasd" e. settings中注册APP f. 顶部 {% load xxoo %} g. {% 函数名 arg1 arg2 %} 缺点: 不能作为if条件 优点: 参数任意 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条件 分页(自定义的分页) XSS: {{ page_str|safe }} mark_safe(page_str) cookie 客户端浏览器上的一个文件 {"user": 'dachengzi'} session :装饰器 Models - 一大波操作 Form验证 - 缓存 中间件 信号 CSRF Admin/ModelForm 作业: 主机管理: 1、单表操作 2、一对多 3、多对多 要求: a. 删除对话框 b. 修改,添加新URL c. 基于cookie进行用户认证 d. 定制显示个数 e. 分页 预习: Form: http://www.cnblogs.com/wupeiqi/articles/6144178.html Model:http://www.cnblogs.com/wupeiqi/articles/6216618.html
分页实例:
初始代码:
# 自定义分页
# 全局变量,相当于数据库
# 生成109个数字,每页显示10个,分11页
# (109/10:取整为10,余数大于0,页数+1 -->divmod函数)
content = []
total_num = 1024
for i in range(total_num):
content.append(i)
def tpl4(request):
# 当前页:current_page
# 每页显示数量:show_count
# 总页数:page
# 显示页数:11页
# (1)获取url 根据url分页数字,显示内容数量跟着变化
current_page = request.GET.get('p', 1) #模拟url: /?p=1 获取p值,如果没有数字,默认第一页1
current_page = int(current_page) #获取到的是字符串
# (2)对列表进行切片显示指定数量
# current_content = content[0:10] # 0 - 9 (10个数)
show_count = 10 # 每一页显示的数量 10
start = (current_page - 1) * show_count
end = current_page * show_count
current_content = content[start:end] # 0 - 9 (10个数)
# (3)根据列表(内容)长度,计算总分页数量
page, left = divmod(len(content), show_count) #余数大于0,页数+1
if left:
page = page + 1
# (4)写分页及样式
page_list = []
show_page = 5 # 显示页码数
# 上一页
if current_page == 1:
p = '<a class="page" href="javascript:void(0);">上一页</a>'
else:
p = '<a class="page" href="?p=%s">上一页</a>' %(current_page - 1)
page_list.append(p)
if page < show_page: # 总页数很少, 不够指定页数
start_index = 1
end_index = page + 1
else: # 总页数>指定页数
if current_page < (show_page + 1)/2: # 当前页码小于指定显示页数的一半
start_index = 1
end_index = show_page + 1
else: # 当前页码大于指定显示页数的一半
start_index = current_page - (show_page - 1)/2
end_index = current_page + (show_page + 1)/2
if current_page + (show_page + 1)/2 > page: #current_page + (show_page - 1)/2 > page 效果一样
start_index = page - (show_page -1)
end_index = page + 1
for item in range(int(start_index), int(end_index)):
if item == current_page:
temp = '<a class="page active" href="?p=%s">%s</a>' %(item, item)
else:
temp = '<a class="page" href="?p=%s">%s</a>' % (item, item)
page_list.append(temp)
if current_page == page:
n = '<a class="page" href="javascript:void(0);">下一页</a>'
else:
n = '<a class="page" href="?p=%s">下一页</a>' % (current_page + 1)
page_list.append(n)
jump = '''
<input type="text" /><a id="j1" onclick="goTo(this, '?p=');">GO</a>
<script>
function goTo(ths, base){
var val = ths.previousSibling.value;
location.href = base + val;
}
</script>
'''
page_list.append(jump)
# 将列表元素拼接为字符串即可
page_str = ''.join(page_list)
# page_list = mark_safe(page_list) #不能对列表做安全认证,只能是字符串做安全认证
from django.utils.safestring import mark_safe
page_str = mark_safe(page_str)
return render(request, 'day21-app03/tpl4.html', {'content': current_content, 'page_str': page_str})
html:
{#{% load xxoo %}#} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %} {% endblock %}</title> <link rel="stylesheet" href="/static/common.css"> {% block css %}{% endblock %} </head> <body> <div class="header">{% block content1 %}{% endblock %}</div> {% block content2 %}{% endblock %} {# {% uson 10 50 %}#} {% block js %}{% endblock %} </body> </html>
{% extends 'day21-app03/master.html' %} <!-- 自定义函数声明 --> {% load xxoo %} {% block title %}{% endblock %} {% block css %} <!-- css --> <style> .page{ background-color: dodgerblue; color: white; display: inline-block; padding: 5px; margin: 5px; } .active{ background-color: red; } </style> {% endblock %} {% block content1 %} 页面分页 {% uson 10 50 %} <!-- 自定义函数调用 --> {% endblock %} {% block content2 %} {% for foo in content %} <!-- 分页内容 --> <li>{{ foo }}</li> {% endfor %} {{ page_str }} <div> 自定义展示内容数量,基于Cookie实现 <select id="def_content" onchange="changePageSize(this);"> <option value="10">10</option> <option value="30">30</option> <option value="50">50</option> <option value="100">100</option> </select> </div> <script src="/static/jquery-1.12.4.js"></script> <!-- jquery的插件,必须写在jquery下面 --> <script src="/static/day21-app03/jquery.cookie.js"></script> <script> $(function () { // 当框架加载完成之后,就给select一个默认值 var v = $.cookie('show_count'); {#var v = $.cookie('show_count', {'path':'/uson/tpl4/'});#} $('#def_content').val(v); // 用class问题多多,他娘个腚的只能用id,不知道什么鬼 //location.reload(); }); function changePageSize(ths){ //var v = ths.value; var v = $(ths).val(); console.log(v); $.cookie('show_count', v); // 设置cookie {#$.cookie('show_count', v, {'path':'/uson/tpl4/'}); 设置应用的指定路径,其他路径无法应用#} location.reload(); } </script> {% endblock %}
改成类的封装:
# 改成类的封装 from utils import pagenation def tpl_class(request): current_page = request.GET.get('p', 1) # 模拟url: /?p=1 获取p值,如果没有数字,默认第一页1 current_page = int(current_page) # 获取到的是字符串 # 基于Cookie,增加显示内容数量 num = request.COOKIES.get('show_count') # 获取到的是字符串 print(num) num = int(num) # (2)对列表进行切片显示指定数量 page_obj = pagenation.Page(current_page, len(content), num) current_content = content[page_obj.start:page_obj.end] # 0 - 9 (10个数)@property 避免了函数带括号 # (3)根据列表(内容)长度,计算总分页数量 page_str = page_obj.page_handle() return render(request, 'day21-app03/tpl4.html', {'content': current_content, 'page_str': page_str})
pagenation.py:
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Uson from django.utils.safestring import mark_safe class Page(object): def __init__(self, current_page, data_count, show_count=10, show_page=5): # 当前页码:current_page # 显示的页码数:show_page # 每页显示的内容条数:show_count # 列表的长度:data_count self.current_page = current_page self.show_count = show_count self.show_page = show_page self.data_count = data_count @property #下面调用的时候就不能带括号了,它已变成属性方法了 def start(self): return (self.current_page - 1) * self.show_count @property def end(self): return self.current_page * self.show_count def page_handle(self): page, left = divmod(self.data_count, self.show_count) # 余数大于0,分页除法整数+1 if left: page = page + 1 # (4)写分页及样式 page_list = [] # 上一页 if self.current_page == 1: p = '<a class="page" href="javascript:void(0);">上一页</a>' else: p = '<a class="page" href="?p=%s">上一页</a>' % (self.current_page - 1) page_list.append(p) if page < self.show_page: start_index = 1 end_index = page + 1 else: if self.current_page < (self.show_page + 1) / 2: start_index = 1 end_index = self.show_page + 1 else: start_index = self.current_page - (self.show_page - 1) / 2 end_index = self.current_page + (self.show_page + 1) / 2 if self.current_page + (self.show_page + 1) / 2 > page: # current_page + (show_page - 1)/2 > page 效果一样 start_index = page - (self.show_page - 1) end_index = page + 1 for item in range(int(start_index), int(end_index)): if item == self.current_page: temp = '<a class="page active" href="?p=%s">%s</a>' % (item, item) else: temp = '<a class="page" href="?p=%s">%s</a>' % (item, item) page_list.append(temp) if self.current_page == page: n = '<a class="page" href="javascript:void(0);">下一页</a>' else: n = '<a class="page" href="?p=%s">下一页</a>' % (self.current_page + 1) page_list.append(n) jump = ''' <input type="text" /><a id="j1" onclick="goTo(this, '?p=');">GO</a> <script> function goTo(ths, base){ var val = ths.previousSibling.value; location.href = base + val; } </script> ''' page_list.append(jump) page_str = ''.join(page_list) # 将列表元素拼接为字符串即可 page_str = mark_safe(page_str) return page_str