django学习之路
Posted polly-ling
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django学习之路相关的知识,希望对你有一定的参考价值。
<p><input type="text" name="name" placeholder="老师姓名" /></p> placeholder 默认显示的字符信息 <select multiple size="10" name="class_ids"> multiple 多选 size 框大小 1. 母版 layout.html {% block x1 %}{%endblock%} <h1>ff</h1> {% block x2 %}{%endblock%} <h1>2</h1>... {% block x3 %}{%endblock%} index.html {%extends ‘layout‘%} {% block x1 %}dfssssssdfsd{%endblock%} {% block x2 %}dfsdfsd{%endblock%} {% block x3 %}fff{%endblock%} 3. Cookie 在浏览器上保存的键值对 def index(request): request.COOKIES request.get_signed_cookie(‘k1‘,salt=‘ff‘) obj = HttpReponse(..) obj = render(...) obj = redirect(..) obj.set_cookie(k1,v1,max_age) obj.set_signed_cookie(k1,v1,max_age,salt=‘fff‘) 4. BootStrap响应式布局 - css - js(欠) 5. 后台布局 1. position: absolute 2. .c1:hover .c2{ } 坦白: project - app01 自己创建的目录, - views.py - SQLHelper 封装SQL操作 Django: - 路由 - 视图 - 模板 - ORM(类-表;对象-行; pymysql连接数据库) Torando: - 路由 - 视图 - 模板 - 自由:pymysql;SqlAchemy Flask: - 路由 - 视图 - 模板(第三方的组件) - 自由:pymysql;SqlAchemy 1. 创建app 2. 数据库操作 Django目录介绍 django-admin startproject mysite cd mysite python manage.py starapp app01 project - app01 - admin Django自带后台管理相关配置 - modal 写类,根据类创建数据库表 - test 单元测试 - views 业务处理 - app02 - app03 1. 路由系统 url -> 函数 a. /login/ -> def login b. /add-user/(d+)/ -> def add_user(request,a1) c. /add-user/(?P<a1>d+)/ -> def add_user(request,a1) PS: 终止符: ^edit$ 伪静态 url(r‘^edit/(w+).html$‘, views.edit), d. 路由分发 urls.py url(r‘^app01/‘, include(‘app01.urls‘)), app01.urls.py url(r‘^index.html$‘, views.index), e. /add-user/(d+)/ -> def add_user(request,a1) name=n1 根据名称可以反向生成URL 1. 在Python代码中 from django.urls import reverse v = reverse(‘n1‘,kwargs={‘a1‘:1111}) print(v) 2. url(r‘^login/‘, views.login,name=‘m1‘) {% url "m1" %} cookies 相关 设置cookie set_cookie key value 设置超时时间 推荐使用max_age= 秒 expires=指定的日期 配合datatime使用 path 默认是‘/‘ 指定url访问cookie domain 域名划分 默认当前域名 一般用不到 sso 统一认证登录 会用到 安全相关 secure=False 给https提供的功能 httponly=False 等于true的时候,只能通过http请求发送,js代码无法获取到 cookie签名 set_signed_cookie key= ‘‘ value=‘‘ salt=‘加密‘ 类似MD5中的加盐 获取 res = request.get_signedcookie(key,salt=‘‘) 自定制签名 装饰器 登录认证 内容整理 1 bootstrap 响应式布局 @media() 最大宽度 2 栅格: 分成12分 随着宽度改变 样式改变 3 表格 4 导航条 5 路径导航 6 fontawesome 图标 7 布局 positione:absolute fix 固定位置 内容 overflout 8 .xx:hover .xx{ } 当鼠标移动的xx样式的标签上时,其子标签的xx应用以下的属性 9 django母版 共同的东西只写一遍 母版: { % block s1 % } { % endblock% } 子版 {% extends "layout.html "%} { % block s1 % } ... ... { % endblock% } 10 用户登录 -cookie: 保存在浏览器端的键值对 设置超时时间 path domain 等参数 发送http请求时,在请求头中携带当前所有访问的cookie 在响应头中 - 写cookie @xzxx def index(request): obj = HttpResponse(‘...‘) obj.set_cookie(.....) request.COOKIES.get(...) 或者 obj.set_signed_cookie(.....) request.get_signed_cookie(....) - 自定义cookie签名 - 装饰器装饰views中的函数 检测用户登录 练习 今日作业: 1. 布局+代码 2. 登录+cookie+装饰器 3. 布局页面HTML+CSS django 路由 1 一对一路由 一个url 对应一个函数 url -> 函数 a. /login/ -> def login b. /add-user/(d+)/ -> def add_user(request,a1) c. /add-user/(?P<a1>d+)/ -> def add_user(request,a1) 2 正则表达式路由 3 路由分发 针对不同app from django.urls import path,re_path,include incloud(‘xxx‘) 字符串 path(‘app01/‘, include(‘app01.urls‘)), app01 re_path(‘edit/(w+)/‘, views.edit), 路由中别名name re_path(‘edit/(w+)/‘, views.edit,name=‘n1‘), html action=“{% url "n1" X %}” 反转url 路由 reverce 函数内部处理 from django.urls import reverse url = reverse(viewname,args=(‘‘,)或者kwargs={‘a1‘:‘xxx‘,}) print(reverse("n1",args=(123,))) 4 终止符 $ 正则匹配路由,以$结尾, ^edit$ 5 伪静态 xxx.html$ 路由中必须已index$ 结尾。 伪静态 url(r‘^edit/(w+).html$‘, views.edit), django ORM操作 Http请求: url -> 视图(模板+数据) 连接数据库操作步骤: 1. 创建数据库 2. 修改project中默认连接sqlit为mysql ,setting中设置 DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.mysql‘, ‘NAME‘:‘s4day70db‘, 数据库名称 ‘USER‘: ‘root‘, ‘PASSWORD‘: ‘‘, ‘HOST‘: ‘localhost‘, ‘PORT‘: 3306, } } 3. 在同project同名文件下的init.py 添加 否则会用默认的工具链接mysql import pymysql pymysql.install_as_MySQLdb() 4 创建表 app01 models中 from django.db import models # Create your models here. class UserInfo(models.Model): nid = models.BigAutoField(primary_key=True) #默认会创建一列id自增主键 username = models.CharField(max_length=32) #CharField 必须有max_length password = models.CharField(max_length=64) 5 注册app setting中 INSTALLED_APPS 添加app的名字 “ ” 6 创建数据表 终端执行 ********** python manage.py makemigrations python manage.py migrate 7 创建数据表 class UserGroup(models.Model): ‘‘‘ 部门 ‘‘‘ title = models.CharField(max_length=32) class UserInfo(models.Model): ‘‘‘ 员工 ‘‘‘ nid = models.BigAutoField(primary_key=True) username = models.CharField(max_length=32) password = models.CharField(max_length=64) age = models.IntegerField(default=1) #创建外键 生成的列名为 ug_id ug = models.ForeignKey(‘UserGroup‘,null=True) 8 单表操作 class UserGroup(models.Model): """ 部门 """ title = models.CharField(max_length=32) --------------------------------------------------- """ 添加 models.UserGroup.objects.create(title=‘销售部‘) 删除 models.UserGroup.objects.filter(id=2).delete() 更新 models.UserGroup.objects.filter(id=2).update(title=‘公关部‘) 查询 group_list = models.UserGroup.objects.all() 默认都是Queryset[obj,obj,] 只查询第一个 就不是queryset类型,直接是第一个对象 group_list = models.UserGroup.objects.all().first() 查询条件 group_list = models.UserGroup.objects.filter(id=1) group_list = models.UserGroup.objects.filter(id__gt=1) group_list = models.UserGroup.objects.filter(id__lt=1) """ 修改数据库: 直接修改名称 然后执行两条命令 age = models.IntegerField(null=True) 或者default=1, #外键 连表操作 跨表去数据 针对对象 基础语法 # 获取 # QuerySet[obj,obj,obj] # result = models.UserInfo.objects.all() # for obj in result: # print(obj.name,obj.age,obj.ut_id,obj.ut.title) # UserInfo,ut是FK字段 - 正向操作 PS: 一个用户只有一个用户类型 # obj = models.UserInfo.objects.all().first() # print(obj.name,obj.age,obj.ut.title) # UserType, 表名小写_set.all() - 反向操作 PS: 一个用户类型下可以有很多用户 # obj = models.UserType.objects.all().first() # print(‘用户类型‘,obj.id,obj.title) # for row in obj.userinfo_set.all(): # print(row.name,row.age) # 数据获取多个数据时 all values values_list # 1. [obj,obj,obj,] # models.UserInfo.objects.all() # models.UserInfo.objects.filter(id__gt=1) # result = models.UserInfo.objects.all() # for item in result: # print(item.name,item.ut.title) # 2. [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},] # models.UserInfo.objects.all().values(‘id‘,‘name‘) # models.UserInfo.objects.filter(id__gt=1).values(‘id‘,‘name‘) # 无法跨表 当前字典内没连表的内容,后续也无法跨表 # result = models.UserInfo.objects.all().values(‘id‘,‘name‘) # for item in result: # print(item[‘id‘],item[‘name‘]) # # 夸表 双下划线 __ 把连表的值 也取到字典内 # result = models.UserInfo.objects.all().values(‘id‘,‘name‘,"ut__title") # for item in result: # print(item[‘id‘],item[‘name‘],item[‘ut__title‘]) # 3. [(1,df),(2,‘df‘)] # models.UserInfo.objects.all().values_list(‘id‘,‘name‘) # models.UserInfo.objects.filter(id__gt=1).values_list(‘id‘,‘name‘) # 无法跨表 # result = models.UserInfo.objects.all().values_list(‘id‘,‘name‘) # for item in result: # print(item[0],item[1]) # 夸表 __ # result = models.UserInfo.objects.all().values_list(‘id‘,‘name‘,"ut__title") # for item in result: # print(item[0],item[1],item[2]) # 3. 排序 user_list = models.UserInfo.objects.all().order_by(‘-id‘,‘name‘) # 4. 分组 from django.db.models import Count,Sum,Max,Min # v =models.UserInfo.objects.values(‘ut_id‘).annotate(xxxx=Count(‘id‘)) # print(v.query) # v =models.UserInfo.objects.values(‘ut_id‘).annotate(xxxx=Count(‘id‘)).filter(xxxx__gt=2) # print(v.query) # v =models.UserInfo.objects.filter(id__gt=2).values(‘ut_id‘).annotate(xxxx=Count(‘id‘)).filter(xxxx__gt=2) # print(v.query) # 5. F,更新时用于获取原来的值 from django.db.models import F,Q # models.UserInfo.objects.all().update(age=F("age")+1) # 6. Q,用于构造复杂查询条件 Q使用有两种方式:对象方式,方法方式 # 应用一:对象方式 # models.UserInfo.objects.filter(Q(id__gt=1)) # models.UserInfo.objects.filter(Q(id=8) | Q(id=2)) # models.UserInfo.objects.filter(Q(id=8) & Q(id=2)) # 应用二:方法方式 # q1 = Q() # q1.connector = ‘OR‘ # q1.children.append((‘id__gt‘, 1)) # q1.children.append((‘id‘, 10)) # q1.children.append((‘id‘, 9)) # # # q2 = Q() # q2.connector = ‘OR‘ # q2.children.append((‘c1‘, 1)) # q2.children.append((‘c1‘, 10)) # q2.children.append((‘c1‘, 9)) # # q3 = Q() # q3.connector = ‘AND‘ # q3.children.append((‘id‘, 1)) # q3.children.append((‘id‘, 2)) # q2.add(q3,‘OR‘) # # con = Q() # con.add(q1, ‘AND‘) # con.add(q2, ‘AND‘) #例子 # 排序 # user_list = models.UserInfo.objects.all().order_by(‘-id‘,‘name‘) # print(user_list) # 分组 from django.db.models import Count,Sum,Max,Min # v =models.UserInfo.objects.values(‘ut_id‘).annotate(xxxx=Count(‘id‘)) # print(v.query) # v =models.UserInfo.objects.values(‘ut_id‘).annotate(xxxx=Count(‘id‘)).filter(xxxx__gt=2) # print(v.query) # v =models.UserInfo.objects.filter(id__gt=2).values(‘ut_id‘).annotate(xxxx=Count(‘id‘)).filter(xxxx__gt=2) # print(v.query) # 过滤 # models.UserInfo.objects.filter(id__gt=1) # models.UserInfo.objects.filter(id__lt=1) # models.UserInfo.objects.filter(id__lte=1) # models.UserInfo.objects.filter(id__gte=1) # models.UserInfo.objects.filter(id__in=[1,2,3]) # models.UserInfo.objects.filter(id__range=[1,2]) # models.UserInfo.objects.filter(name__startswith=‘xxxx‘) # models.UserInfo.objects.filter(name__contains=‘xxxx‘) # models.UserInfo.objects.exclude(id=1) # F,Q,extra # from django.db.models import F # models.UserInfo.objects.all().update(age=F("age")+1) # Q # models.UserInfo.objects.filter(id=1,name=‘root‘) # condition = { # ‘id‘:1, # ‘name‘: ‘root‘ # } # models.UserInfo.objects.filter(**condition) # Q使用有两种方式:对象方式,方法方式* # from django.db.models import Q # models.UserInfo.objects.filter(Q(id__gt=1)) # models.UserInfo.objects.filter(Q(id=8) | Q(id=2)) # models.UserInfo.objects.filter(Q(id=8) & Q(id=2)) # q1 = Q() # q1.connector = ‘OR‘ # q1.children.append((‘id__gt‘, 1)) # q1.children.append((‘id‘, 10)) # q1.children.append((‘id‘, 9)) # # # q2 = Q() # q2.connector = ‘OR‘ # q2.children.append((‘c1‘, 1)) # q2.children.append((‘c1‘, 10)) # q2.children.append((‘c1‘, 9)) # # q3 = Q() # q3.connector = ‘AND‘ # q3.children.append((‘id‘, 1)) # q3.children.append((‘id‘, 2)) # q2.add(q3,‘OR‘) # # con = Q() # con.add(q1, ‘AND‘) # con.add(q2, ‘AND‘) # condition_dict = { # ‘k1‘:[1,2,3,4], # ‘k2‘:[1,], # } # con = Q() # for k,v in condition_dict.items(): # q = Q() # q.connector = ‘OR‘ # for i in v: # q.children.append((‘id‘, i)) # con.add(q,‘AND‘) # models.UserInfo.objects.filter(con) # # q1 = Q() # q1.connector = ‘OR‘ # q1.children.append((‘id‘, 1)) # q1.children.append((‘id‘, 10)) # q1.children.append((‘id‘, 9)) # # # q2 = Q() # q2.connector = ‘OR‘ # q2.children.append((‘c1‘, 1)) # q2.children.append((‘c1‘, 10)) # q2.children.append((‘c1‘, 9)) # # q3 = Q() # q3.connector = ‘AND‘ # q3.children.append((‘id‘, 1)) # q3.children.append((‘id‘, 2)) # q2.add(q3,‘OR‘) # # con = Q() # con.add(q1, ‘AND‘) # con.add(q2, ‘AND‘) # (id=1 or id = 10 or id=9 or (id=1 and id=2)) and (c1=1 or c1=10 or c1=9) # 7. extra, 额外查询条件以及相关表,排序 models.UserInfo.objects.filter(id__gt=1) models.UserInfo.objects.all() # id name age ut_id models.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None) # a. 映射 # select # select_params=None # select 此处 from 表 # b. 条件 # where=None # params=None, # select * from 表 where 此处 # c. 表 # tables # select * from 表,此处 # c. 排序 # order_by=None # select * from 表 order by 此处 models.UserInfo.objects.extra( select={‘newid‘:‘select count(1) from app01_usertype where id>%s‘}, select_params=[1,], where = [‘age>%s‘], params=[18,], order_by=[‘-age‘], tables=[‘app01_usertype‘] ) """ select app01_userinfo.id, (select count(1) from app01_usertype where id>1) as newid from app01_userinfo,app01_usertype where app01_userinfo.age > 18 order by app01_userinfo.age desc """ result = models.UserInfo.objects.filter(id__gt=1).extra( where=[‘app01_userinfo.id < %s‘], params=[100,], tables=[‘app01_usertype‘], order_by=[‘-app01_userinfo.id‘], select={‘uid‘:1,‘sw‘:"select count(1) from app01_userinfo"} ) print(result.query) # SELECT (1) AS "uid", (select count(1) from app01_userinfo) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" FROM "app01_userinfo" , "app01_usertype" WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) ORDER BY ("app01_userinfo".id) DESC # 8. 原生SQL语句 from django.db import connection, connections cursor = connection.cursor() # connection=default数据 cursor = connections[‘db2‘].cursor() #setting中的database名称 cursor.execute("""SELECT * from auth_user where id = %s""", [1]) row = cursor.fetchone() row = cursor.fetchall() - 原生SQL语句 - raw result = models.UserInfo.objects.raw(‘select * from userinfo‘) [obj(UserInfo),obj,] result = models.UserInfo.objects.raw(‘select id,1 as name,2 as age,4 as ut_id from usertype‘) [obj(UserInfo),obj,] v1 = models.UserInfo.objects.raw(‘SELECT id,title FROM app01_usertype‘,translations=name_map) # 9. 简单的操作 http://www.cnblogs.com/wupeiqi/articles/6216618.html 9 其他 http://www.cnblogs.com/wupeiqi/articles/6216618.html 其他操作 # v = models.UserInfo.objects.all().only(‘id‘,‘name‘) # v = models.UserInfo.objects.all().defer(‘name‘) 除了name列 models.UserInfo.objects.all().using(‘db2‘) 用哪个数据库 setting中database的 . models.UserInfo.objects.all().filter().all().exclude().only().defer() 可以一直去下去 因为是queryset类型的对象 有。方法,别的不行 分组 aggregate distinct # models.UserInfo.objects.none() # result = models.UserInfo.objects.aggregate(k=Count(‘ut_id‘, distinct=True), n=Count(‘id‘)) # print(result) #新增 返回的对象 就是新增的数据 # obj = models.UserType.objects.create(title=‘xxx‘) # obj = models.UserType.objects.create(**{‘title‘: ‘xxx‘}) # print(obj.id) save保存后才会数据库创建 # obj = models.UserType(title=‘xxx‘) # obj.save() 批量增加 def bulk_create(self, objs, batch_size=None): # 批量插入 # batch_size表示一次插入的个数 objs = [ models.DDD(name=‘r11‘), models.DDD(name=‘r22‘) ] models.DDD.objects.bulk_create(objs, 10) def get_or_create(self, defaults=None, **kwargs): # 如果存在,则获取,否则,创建 # defaults 指定创建时,其他字段的值 obj, created = models.UserInfo.objects.get_or_create(username=‘root1‘, defaults={‘email‘: ‘1111111‘,‘u_id‘: 2, ‘t_id‘: 2}) created 返回的为 True或者是false def update_or_create(self, defaults=None, **kwargs): # 如果存在,则更新,否则,创建 # defaults 指定创建时或更新时的其他字段 obj, created = models.UserInfo.objects.update_or_create(username=‘root1‘, defaults={‘email‘: ‘1111111‘,‘u_id‘: 2, ‘t_id‘: 1}) 根据主键查询 # models.UserInfo.objects.filter(id__in=[1,2,3]) # models.UserInfo.objects.in_bulk([1,2,3]) ==========================补充1==========================select_related prefetch_related # q = models.UserInfo.objects.all() # select * from userinfo # select * from userinfo inner join usertype on ... # for row in q: # print(row.name,row.ut.title) # select_related: 查询主动做连表 # q = models.UserInfo.objects.all().select_related(‘ut‘,‘gp‘) # select * from userinfo # select * from userinfo inner join usertype on ... # for row in q: # print(row.name,row.ut.title) # prefetch_related: 不做连表,做多次查询 # q = models.UserInfo.objects.all().prefetch_related(‘ut‘) # select * from userinfo; # Django内部:ut_id = [2,4] # select * from usertype where id in [2,4] # for row in q: # print(row.id,row.ut.title) # 多对多 # objs = [ # models.Boy(name=‘方少伟‘), # models.Boy(name=‘由秦兵‘), # models.Boy(name=‘陈涛‘), # models.Boy(name=‘闫龙‘), # models.Boy(name=‘吴彦祖‘), # ] # models.Boy.objects.bulk_create(objs,5) # # objss = [ # models.Girl(nick=‘小鱼‘), # models.Girl(nick=‘小周‘), # models.Girl(nick=‘小猫‘), # models.Girl(nick=‘小狗‘), # ] # models.Girl.objects.bulk_create(objss,5) # models.Love.objects.create(b_id=1,g_id=1) # models.Love.objects.create(b_id=1,g_id=4) # models.Love.objects.create(b_id=2,g_id=4) # models.Love.objects.create(b_id=2,g_id=2) # 1. 和方少伟有关系的姑娘 # obj = models.Boy.objects.filter(name=‘方少伟‘).first() # love_list = obj.love_set.all() # for row in love_list: # print(row.g.nick) # # # love_list = models.Love.objects.filter(b__name=‘方少伟‘) # for row in love_list: # print(row.g.nick) # # love_list = models.Love.objects.filter(b__name=‘方少伟‘).values(‘g__nick‘) # for item in love_list: # print(item[‘g__nick‘]) # # love_list = models.Love.objects.filter(b__name=‘方少伟‘).select_related(‘g‘) # for obj in love_list: # print(obj.g.nick) 第三章关系表 可以自己定义类 或者使用内置的生成,但是只能生成三列,两者合用 # m = models.ManyToManyField(‘Boy‘) 生成第三张关系表 #m = models.ManyToManyField(‘Girl‘,through="Love",through_fields=(‘b‘,‘g‘,)) 告诉django通过love连接,love表的b‘,‘g‘, 来关联 只提供查询和清空的功能 class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField(‘Girl‘,through="Love",through_fields=(‘b‘,‘g‘,)) class Girl(models.Model): nick = models.CharField(max_length=32) # m = models.ManyToManyField(‘Boy‘) class Love(models.Model): b = models.ForeignKey(‘Boy‘) g = models.ForeignKey(‘Girl‘) #联合唯一索引 class Meta: unique_together = [ (‘b‘,‘g‘), ] # obj = models.Boy.objects.filter(name=‘方少伟‘).first() # print(obj.id,obj.name) # obj.m.add(2) # obj.m.add(2,4) # obj.m.add(*[1,]) # obj.m.remove(1) # obj.m.remove(2,3) # obj.m.remove(*[4,]) # obj.m.set([1,]) # q = obj.m.all() # # [Girl对象] # print(q) # obj = models.Boy.objects.filter(name=‘方少伟‘).first() # girl_list = obj.m.all() # obj = models.Boy.objects.filter(name=‘方少伟‘).first() # girl_list = obj.m.all() # girl_list = obj.m.filter(nick=‘小鱼‘) # print(girl_list) # obj = models.Boy.objects.filter(name=‘方少伟‘).first() # obj.m.clear() # obj = models.Girl.objects.filter(nick=‘小鱼‘).first() # print(obj.id,obj.nick) # v = obj.boy_set.all() # print(v) 编写ORM app01 -- models 中 创建表 ORM操作表: 创建表 修改表 删除表 操作数据行: 增删改查 ORM利用pymysql第三方工具连接数据库 默认: SQLlite MySQL: mysql -> MySQLDB(修改django默认连接mySQL方式) XSS 跨站脚本攻击 -慎用safe 和mark_safe(导入模块 ) from django.utils.safestring import mark_safe safe 在html中表明 -非要用,一定要过滤关键字 csrf 一般post提交的时候验证 FBv使用方法 a.基本应用 在form中添加 {% csrf_token %} {{ csrf_token }} 页面会显示随机字符串信息 b. 全局禁用 setting中 ‘django.middleware.csrf.CsrfViewMiddleware‘, 注释 c. 局部禁用 全局使用,在函数上添加装饰器 from django.views.decorators.csrf import csrf_exempt @csrf_exempt def index(): pass d.局部使用 全局禁用 在函数上添加装饰器 from django.views.decorators.csrf import csrf_protect @csrf_protect def index(): pass CBV使用装饰器方法 from django.views import View from django.utils.decorators import method_decorator # 1. CBV应用装饰器 def wrapper(func): def inner(*args,**kwargs): return func(*args,**kwargs) return inner # 1. 指定方法上添加装饰器 # class Foo(View): # # @method_decorator(csrf_protect) # def get(self,request): # pass # # def post(self,request): # pass # 2. 在类上添加 # @method_decorator(csrf_protect,name=‘dispatch‘) #cbv中所有的提交都会先到dispatch # class Foo(View): # # def get(self,request): # pass # # def post(self,request): # pass Ajax提交数据时候,携带CSRF: a. 放置在data中携带 <form method="POST" action="/csrf1.html"> {% csrf_token %} <input id="user" type="text" name="user" /> <input type="submit" value="提交"/> <a onclick="submitForm();">Ajax提交</a> </form> <script src="/static/jquery-1.12.4.js"></script> <script> function submitForm(){ var csrf = $(‘input[name="csrfmiddlewaretoken"]‘).val(); var user = $(‘#user‘).val(); $.ajax({ url: ‘/csrf1.html‘, type: ‘POST‘, data: { "user":user,‘csrfmiddlewaretoken‘: csrf}, success:function(arg){ console.log(arg); } }) } </script> b. 放在请求头中 <form method="POST" action="/csrf1.html"> {% csrf_token %} <input id="user" type="text" name="user" /> <input type="submit" value="提交"/> <a onclick="submitForm();">Ajax提交</a> </form> <script src="/static/jquery-1.12.4.js"></script> <script src="/static/jquery.cookie.js"></script> <script> function submitForm(){ var token = $.cookie(‘csrftoken‘); var user = $(‘#user‘).val(); $.ajax({ url: ‘/csrf1.html‘, type: ‘POST‘, headers:{‘X-CSRFToken‘: token}, data: { "user":user}, success:function(arg){ console.log(arg); } }) } </script> django视图 cbv 、 fbv CBV 先dispatch 判断method 反射 如果想做定制化的 可以添加在这里 def dispatch(self, request, *args, **kwargs): print("before") obj=super(Login, self).dispatch(request,*args,**kwargs) print("after") return obj url中设置 re_path(‘classes/‘,views.Login.as_view),固定用法 view设置为 form表单只有post 和 get 方法,ajex 支持所有 from django.views import View class Login(View): ‘‘‘ 请求方法基本常用的 get 查询 post 创建 put 更新 delete 删除 ‘‘‘ def dispatch(self, request, *args, **kwargs): print("before") obj=super(Login, self).dispatch(request,*args,**kwargs) print("after") return obj def get(self,request): pass def put(self,request): pass django 分页操作 分批获取数据 models.UserInfo.objects.all()[0:10] models.UserInfo.objects.all()[10:20] ---django 自带提供的的分页 from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage def index(request): """ 分页 :param request: :return: """ # for i in range(300): # name = "root" + str(i) # models.UserInfo.objects.create(name=name,age=18,ut_id=1) current_page = request.GET.get(‘page‘) user_list = models.UserInfo.objects.all() paginator = Paginator(user_list,10) # per_page: 每页显示条目数量 # count: 数据总个数 # num_pages:总页数 # page_range:总页数的索引范围,如: (1,10),(1,200) # page: page对象 try: posts = paginator.page(current_page) except PageNotAnInteger as e: posts = paginator.page(1) except EmptyPage as e: posts = paginator.page(1) # has_next 是否有下一页 # next_page_number 下一页页码 # has_previous 是否有上一页 # previous_page_number 上一页页码 # object_list 分页之后的数据列表 # number 当前页 # paginator paginator对象 return render(request,‘index.html‘,{‘posts‘:posts}) --自定义分页组件 from utils.pager import PageInfo def custom(request): # 表示用户当前想要访问的页码: 8 all_count = models.UserInfo.objects.all().count() page_info = PageInfo(request.GET.get(‘page‘),all_count,10,‘/custom.html‘,11) user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()] return render(request,‘custom.html‘,{‘user_list‘:user_list,‘page_info‘:page_info}) class PageInfo(object): def __init__(self,current_page,all_count,per_page,base_url,show_page=11): """ :param current_page: :param all_count: 数据库总行数 :param per_page: 每页显示函数 :return: """ try: self.current_page = int(current_page) except Exception as e: self.current_page = 1 self.per_page = per_page a,b = divmod(all_count,per_page) if b: a = a +1 self.all_pager = a self.show_page = show_page self.base_url = base_url def start(self): return (self.current_page-1) * self.per_page def end(self): return self.current_page * self.per_page def pager(self): # v = "<a href=‘/custom.html?page=1‘>1</a><a href=‘/custom.html?page=2‘>2</a>" # return v page_list = [] half = int((self.show_page-1)/2) # 如果数据总页数 < 11 if self.all_pager < self.show_page: begin = 1 stop = self.all_pager + 1 # 如果数据总页数 > 11 else: # 如果当前页 <=5,永远显示1,11 if self.current_page <= half: begin = 1 stop = self.show_page + 1 else: if self.current_page + half > self.all_pager: begin = self.all_pager - self.show_page + 1 stop = self.all_pager + 1 else: begin = self.current_page - half stop = self.current_page + half + 1 if self.current_page <= 1: prev = "<li><a href=‘#‘>上一页</a></li>" else: prev = "<li><a href=‘%s?page=%s‘>上一页</a></li>" %(self.base_url,self.current_page-1,) page_list.append(prev) for i in range(begin,stop): if i == self.current_page: temp = "<li class=‘active‘><a href=‘%s?page=%s‘>%s</a></li>" %(self.base_url,i,i,) else: temp = "<li><a href=‘%s?page=%s‘>%s</a></li>" %(self.base_url,i,i,) page_list.append(temp) if self.current_page >= self.all_pager: nex = "<li><a href=‘#‘>下一页</a></li>" else: nex = "<li><a href=‘%s?page=%s‘>下一页</a></li>" %(self.base_url,self.current_page+1,) page_list.append(nex) return ‘‘.join(page_list) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" /> </head> <body> <h1>用户列表</h1> <ul> {% for row in user_list %} <li>{{ row.name }}</li> {% endfor %} </ul> <nav aria-label="Page navigation"> <ul class="pagination"> {{ page_info.pager|safe }} </ul> </nav> </body> </html>
<p><input type="text" name="name" placeholder="老师姓名" /></p>
placeholder 默认显示的字符信息
<select multiple size="10" name="class_ids"> multiple 多选 size 框大小
1. 母版layout.html{% block x1 %}{%endblock%}<h1>ff</h1>{% block x2 %}{%endblock%}<h1>2</h1>...{% block x3 %}{%endblock%}index.html{%extends ‘layout‘%}{% block x1 %}dfssssssdfsd{%endblock%}{% block x2 %}dfsdfsd{%endblock%}{% block x3 %}fff{%endblock%}3. Cookie在浏览器上保存的键值对def index(request):request.COOKIESrequest.get_signed_cookie(‘k1‘,salt=‘ff‘)obj = HttpReponse(..)obj = render(...)obj = redirect(..)obj.set_cookie(k1,v1,max_age)obj.set_signed_cookie(k1,v1,max_age,salt=‘fff‘)4. BootStrap响应式布局- css- js(欠)5. 后台布局1. position: absolute2. .c1:hover .c2{}坦白:project- app01 自己创建的目录,- views.py- SQLHelper 封装SQL操作Django:- 路由- 视图- 模板- ORM(类-表;对象-行; pymysql连接数据库)Torando:- 路由- 视图- 模板- 自由:pymysql;SqlAchemyFlask:- 路由- 视图- 模板(第三方的组件)- 自由:pymysql;SqlAchemy1. 创建app2. 数据库操作
Django目录介绍django-admin startproject mysitecd mysitepython manage.py starapp app01project- app01- admin Django自带后台管理相关配置- modal 写类,根据类创建数据库表- test 单元测试- views 业务处理- app02- app03
1. 路由系统url -> 函数a. /login/ -> def loginb. /add-user/(d+)/ -> def add_user(request,a1)c. /add-user/(?P<a1>d+)/ -> def add_user(request,a1)PS: 终止符:^edit$伪静态url(r‘^edit/(w+).html$‘, views.edit),d. 路由分发urls.pyurl(r‘^app01/‘, include(‘app01.urls‘)),app01.urls.pyurl(r‘^index.html$‘, views.index),e. /add-user/(d+)/ -> def add_user(request,a1) name=n1根据名称可以反向生成URL1. 在Python代码中from django.urls import reversev = reverse(‘n1‘,kwargs={‘a1‘:1111})print(v)2. url(r‘^login/‘, views.login,name=‘m1‘){% url "m1" %}
cookies 相关设置cookieset_cookiekeyvalue 设置超时时间 推荐使用max_age= 秒 expires=指定的日期 配合datatime使用
path 默认是‘/‘ 指定url访问cookie
domain 域名划分 默认当前域名 一般用不到 sso 统一认证登录 会用到
安全相关secure=False 给https提供的功能httponly=False 等于true的时候,只能通过http请求发送,js代码无法获取到
cookie签名set_signed_cookiekey= ‘‘value=‘‘salt=‘加密‘类似MD5中的加盐
获取res = request.get_signedcookie(key,salt=‘‘)
自定制签名
装饰器 登录认证
内容整理1 bootstrap 响应式布局 @media() 最大宽度2 栅格:分成12分 随着宽度改变 样式改变3 表格4 导航条
5 路径导航
6 fontawesome 图标
7 布局 positione:absolute fix 固定位置内容 overflout
8 .xx:hover .xx{ }当鼠标移动的xx样式的标签上时,其子标签的xx应用以下的属性
9 django母版 共同的东西只写一遍母版:{ % block s1 % }
{ % endblock% }
子版{% extends "layout.html "%}{ % block s1 % }......{ % endblock% }
10 用户登录 -cookie: 保存在浏览器端的键值对 设置超时时间 path domain 等参数 发送http请求时,在请求头中携带当前所有访问的cookie 在响应头中
- 写[email protected] index(request):obj = HttpResponse(‘...‘)obj.set_cookie(.....)request.COOKIES.get(...)或者obj.set_signed_cookie(.....)request.get_signed_cookie(....)
- 自定义cookie签名- 装饰器装饰views中的函数 检测用户登录
练习今日作业:1. 布局+代码2. 登录+cookie+装饰器3. 布局页面HTML+CSS
django 路由
1 一对一路由 一个url 对应一个函数url -> 函数a. /login/ -> def loginb. /add-user/(d+)/ -> def add_user(request,a1)c. /add-user/(?P<a1>d+)/ -> def add_user(request,a1)
2 正则表达式路由
3 路由分发 针对不同app from django.urls import path,re_path,includeincloud(‘xxx‘) 字符串
path(‘app01/‘, include(‘app01.urls‘)),
app01 re_path(‘edit/(w+)/‘, views.edit),
路由中别名name re_path(‘edit/(w+)/‘, views.edit,name=‘n1‘),
htmlaction=“{% url "n1" X %}”
反转url 路由 reverce 函数内部处理from django.urls import reverseurl = reverse(viewname,args=(‘‘,)或者kwargs={‘a1‘:‘xxx‘,})print(reverse("n1",args=(123,)))
4 终止符 $正则匹配路由,以$结尾,^edit$
5 伪静态 xxx.html$路由中必须已index$ 结尾。伪静态url(r‘^edit/(w+).html$‘, views.edit),
django ORM操作
Http请求:url -> 视图(模板+数据)
连接数据库操作步骤:1. 创建数据库
2. 修改project中默认连接sqlit为mysql ,setting中设置DATABASES = {‘default‘: {‘ENGINE‘: ‘django.db.backends.mysql‘,‘NAME‘:‘s4day70db‘, 数据库名称‘USER‘: ‘root‘,‘PASSWORD‘: ‘‘,‘HOST‘: ‘localhost‘, ‘PORT‘: 3306,}}
3. 在同project同名文件下的init.py 添加 否则会用默认的工具链接mysqlimport pymysqlpymysql.install_as_MySQLdb()
4 创建表 app01 models中from django.db import models
# Create your models here.class UserInfo(models.Model): nid = models.BigAutoField(primary_key=True) #默认会创建一列id自增主键 username = models.CharField(max_length=32) #CharField 必须有max_length password = models.CharField(max_length=64)
5 注册app setting中 INSTALLED_APPS 添加app的名字 “ ”
6 创建数据表 终端执行 ********** python manage.py makemigrations python manage.py migrate
7 创建数据表class UserGroup(models.Model): ‘‘‘ 部门 ‘‘‘ title = models.CharField(max_length=32)
class UserInfo(models.Model): ‘‘‘ 员工 ‘‘‘ nid = models.BigAutoField(primary_key=True) username = models.CharField(max_length=32) password = models.CharField(max_length=64) age = models.IntegerField(default=1) #创建外键 生成的列名为 ug_id ug = models.ForeignKey(‘UserGroup‘,null=True)
8 单表操作class UserGroup(models.Model): """ 部门 """ title = models.CharField(max_length=32) ---------------------------------------------------"""添加models.UserGroup.objects.create(title=‘销售部‘)
删除models.UserGroup.objects.filter(id=2).delete()
更新models.UserGroup.objects.filter(id=2).update(title=‘公关部‘)
查询group_list = models.UserGroup.objects.all()默认都是Queryset[obj,obj,]
只查询第一个 就不是queryset类型,直接是第一个对象group_list = models.UserGroup.objects.all().first()
查询条件group_list = models.UserGroup.objects.filter(id=1)group_list = models.UserGroup.objects.filter(id__gt=1)group_list = models.UserGroup.objects.filter(id__lt=1)
"""
修改数据库:直接修改名称 然后执行两条命令 age = models.IntegerField(null=True) 或者default=1,
#外键 连表操作 跨表去数据 针对对象 基础语法 # 获取 # QuerySet[obj,obj,obj] # result = models.UserInfo.objects.all() # for obj in result: # print(obj.name,obj.age,obj.ut_id,obj.ut.title)
# UserInfo,ut是FK字段 - 正向操作 PS: 一个用户只有一个用户类型 # obj = models.UserInfo.objects.all().first() # print(obj.name,obj.age,obj.ut.title)
# UserType, 表名小写_set.all() - 反向操作 PS: 一个用户类型下可以有很多用户 # obj = models.UserType.objects.all().first() # print(‘用户类型‘,obj.id,obj.title) # for row in obj.userinfo_set.all(): # print(row.name,row.age)
# 数据获取多个数据时 all values values_list # 1. [obj,obj,obj,] # models.UserInfo.objects.all() # models.UserInfo.objects.filter(id__gt=1) # result = models.UserInfo.objects.all() # for item in result: # print(item.name,item.ut.title)
# 2. [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},] # models.UserInfo.objects.all().values(‘id‘,‘name‘) # models.UserInfo.objects.filter(id__gt=1).values(‘id‘,‘name‘) # 无法跨表 当前字典内没连表的内容,后续也无法跨表 # result = models.UserInfo.objects.all().values(‘id‘,‘name‘) # for item in result: # print(item[‘id‘],item[‘name‘]) # # 夸表 双下划线 __ 把连表的值 也取到字典内 # result = models.UserInfo.objects.all().values(‘id‘,‘name‘,"ut__title") # for item in result: # print(item[‘id‘],item[‘name‘],item[‘ut__title‘])
# 3. [(1,df),(2,‘df‘)] # models.UserInfo.objects.all().values_list(‘id‘,‘name‘) # models.UserInfo.objects.filter(id__gt=1).values_list(‘id‘,‘name‘) # 无法跨表 # result = models.UserInfo.objects.all().values_list(‘id‘,‘name‘) # for item in result: # print(item[0],item[1]) # 夸表 __ # result = models.UserInfo.objects.all().values_list(‘id‘,‘name‘,"ut__title") # for item in result: # print(item[0],item[1],item[2])
# 3. 排序user_list = models.UserInfo.objects.all().order_by(‘-id‘,‘name‘)# 4. 分组from django.db.models import Count,Sum,Max,Min# v =models.UserInfo.objects.values(‘ut_id‘).annotate(xxxx=Count(‘id‘))# print(v.query)# v =models.UserInfo.objects.values(‘ut_id‘).annotate(xxxx=Count(‘id‘)).filter(xxxx__gt=2)# print(v.query)# v =models.UserInfo.objects.filter(id__gt=2).values(‘ut_id‘).annotate(xxxx=Count(‘id‘)).filter(xxxx__gt=2)# print(v.query)
# 5. F,更新时用于获取原来的值from django.db.models import F,Q# models.UserInfo.objects.all().update(age=F("age")+1)
# 6. Q,用于构造复杂查询条件Q使用有两种方式:对象方式,方法方式# 应用一:对象方式# models.UserInfo.objects.filter(Q(id__gt=1))# models.UserInfo.objects.filter(Q(id=8) | Q(id=2))# models.UserInfo.objects.filter(Q(id=8) & Q(id=2))# 应用二:方法方式# q1 = Q()# q1.connector = ‘OR‘# q1.children.append((‘id__gt‘, 1))# q1.children.append((‘id‘, 10))# q1.children.append((‘id‘, 9))### q2 = Q()# q2.connector = ‘OR‘# q2.children.append((‘c1‘, 1))# q2.children.append((‘c1‘, 10))# q2.children.append((‘c1‘, 9))## q3 = Q()# q3.connector = ‘AND‘# q3.children.append((‘id‘, 1))# q3.children.append((‘id‘, 2))# q2.add(q3,‘OR‘)## con = Q()# con.add(q1, ‘AND‘)# con.add(q2, ‘AND‘)
#例子 # 排序 # user_list = models.UserInfo.objects.all().order_by(‘-id‘,‘name‘) # print(user_list)
# 分组 from django.db.models import Count,Sum,Max,Min # v =models.UserInfo.objects.values(‘ut_id‘).annotate(xxxx=Count(‘id‘)) # print(v.query) # v =models.UserInfo.objects.values(‘ut_id‘).annotate(xxxx=Count(‘id‘)).filter(xxxx__gt=2) # print(v.query) # v =models.UserInfo.objects.filter(id__gt=2).values(‘ut_id‘).annotate(xxxx=Count(‘id‘)).filter(xxxx__gt=2) # print(v.query) # 过滤 # models.UserInfo.objects.filter(id__gt=1) # models.UserInfo.objects.filter(id__lt=1) # models.UserInfo.objects.filter(id__lte=1) # models.UserInfo.objects.filter(id__gte=1) # models.UserInfo.objects.filter(id__in=[1,2,3]) # models.UserInfo.objects.filter(id__range=[1,2]) # models.UserInfo.objects.filter(name__startswith=‘xxxx‘) # models.UserInfo.objects.filter(name__contains=‘xxxx‘) # models.UserInfo.objects.exclude(id=1)
# F,Q,extra # from django.db.models import F # models.UserInfo.objects.all().update(age=F("age")+1)
# Q # models.UserInfo.objects.filter(id=1,name=‘root‘)
# condition = { # ‘id‘:1, # ‘name‘: ‘root‘ # } # models.UserInfo.objects.filter(**condition) # Q使用有两种方式:对象方式,方法方式*
# from django.db.models import Q # models.UserInfo.objects.filter(Q(id__gt=1)) # models.UserInfo.objects.filter(Q(id=8) | Q(id=2)) # models.UserInfo.objects.filter(Q(id=8) & Q(id=2))
# q1 = Q() # q1.connector = ‘OR‘ # q1.children.append((‘id__gt‘, 1)) # q1.children.append((‘id‘, 10)) # q1.children.append((‘id‘, 9)) # # # q2 = Q() # q2.connector = ‘OR‘ # q2.children.append((‘c1‘, 1)) # q2.children.append((‘c1‘, 10)) # q2.children.append((‘c1‘, 9)) # # q3 = Q() # q3.connector = ‘AND‘ # q3.children.append((‘id‘, 1)) # q3.children.append((‘id‘, 2)) # q2.add(q3,‘OR‘) # # con = Q() # con.add(q1, ‘AND‘) # con.add(q2, ‘AND‘)
# condition_dict = { # ‘k1‘:[1,2,3,4], # ‘k2‘:[1,], # } # con = Q() # for k,v in condition_dict.items(): # q = Q() # q.connector = ‘OR‘ # for i in v: # q.children.append((‘id‘, i)) # con.add(q,‘AND‘) # models.UserInfo.objects.filter(con) # # q1 = Q() # q1.connector = ‘OR‘ # q1.children.append((‘id‘, 1)) # q1.children.append((‘id‘, 10)) # q1.children.append((‘id‘, 9)) # # # q2 = Q() # q2.connector = ‘OR‘ # q2.children.append((‘c1‘, 1)) # q2.children.append((‘c1‘, 10)) # q2.children.append((‘c1‘, 9)) # # q3 = Q() # q3.connector = ‘AND‘ # q3.children.append((‘id‘, 1)) # q3.children.append((‘id‘, 2)) # q2.add(q3,‘OR‘) # # con = Q() # con.add(q1, ‘AND‘) # con.add(q2, ‘AND‘) # (id=1 or id = 10 or id=9 or (id=1 and id=2)) and (c1=1 or c1=10 or c1=9)
# 7. extra, 额外查询条件以及相关表,排序models.UserInfo.objects.filter(id__gt=1)models.UserInfo.objects.all() # id name age ut_idmodels.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)# a. 映射# select # select_params=None# select 此处 from 表# b. 条件# where=None# params=None,# select * from 表 where 此处# c. 表# tables# select * from 表,此处# c. 排序# order_by=None# select * from 表 order by 此处models.UserInfo.objects.extra(select={‘newid‘:‘select count(1) from app01_usertype where id>%s‘},select_params=[1,],where = [‘age>%s‘],params=[18,],order_by=[‘-age‘],tables=[‘app01_usertype‘])"""select app01_userinfo.id,(select count(1) from app01_usertype where id>1) as newidfrom app01_userinfo,app01_usertypewhere app01_userinfo.age > 18order by app01_userinfo.age desc"""result = models.UserInfo.objects.filter(id__gt=1).extra(where=[‘app01_userinfo.id < %s‘],params=[100,],tables=[‘app01_usertype‘],order_by=[‘-app01_userinfo.id‘],select={‘uid‘:1,‘sw‘:"select count(1) from app01_userinfo"})print(result.query)# SELECT (1) AS "uid", (select count(1) from app01_userinfo) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" FROM "app01_userinfo" , "app01_usertype" WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) ORDER BY ("app01_userinfo".id) DESC
# 8. 原生SQL语句from django.db import connection, connectionscursor = connection.cursor() # connection=default数据cursor = connections[‘db2‘].cursor() #setting中的database名称cursor.execute("""SELECT * from auth_user where id = %s""", [1])row = cursor.fetchone()row = cursor.fetchall()
- 原生SQL语句- rawresult = models.UserInfo.objects.raw(‘select * from userinfo‘)[obj(UserInfo),obj,]result = models.UserInfo.objects.raw(‘select id,1 as name,2 as age,4 as ut_id from usertype‘)[obj(UserInfo),obj,]v1 = models.UserInfo.objects.raw(‘SELECT id,title FROM app01_usertype‘,translations=name_map)# 9. 简单的操作http://www.cnblogs.com/wupeiqi/articles/6216618.html
9 其他 http://www.cnblogs.com/wupeiqi/articles/6216618.html 其他操作 # v = models.UserInfo.objects.all().only(‘id‘,‘name‘) # v = models.UserInfo.objects.all().defer(‘name‘) 除了name列
models.UserInfo.objects.all().using(‘db2‘) 用哪个数据库 setting中database的 .
models.UserInfo.objects.all().filter().all().exclude().only().defer() 可以一直去下去 因为是queryset类型的对象 有。方法,别的不行
分组 aggregate distinct # models.UserInfo.objects.none() # result = models.UserInfo.objects.aggregate(k=Count(‘ut_id‘, distinct=True), n=Count(‘id‘)) # print(result)
#新增 返回的对象 就是新增的数据 # obj = models.UserType.objects.create(title=‘xxx‘) # obj = models.UserType.objects.create(**{‘title‘: ‘xxx‘}) # print(obj.id)
save保存后才会数据库创建 # obj = models.UserType(title=‘xxx‘) # obj.save()
批量增加def bulk_create(self, objs, batch_size=None): # 批量插入 # batch_size表示一次插入的个数 objs = [ models.DDD(name=‘r11‘), models.DDD(name=‘r22‘) ] models.DDD.objects.bulk_create(objs, 10)
def get_or_create(self, defaults=None, **kwargs): # 如果存在,则获取,否则,创建 # defaults 指定创建时,其他字段的值 obj, created = models.UserInfo.objects.get_or_create(username=‘root1‘, defaults={‘email‘: ‘1111111‘,‘u_id‘: 2, ‘t_id‘: 2})
created 返回的为 True或者是false
def update_or_create(self, defaults=None, **kwargs): # 如果存在,则更新,否则,创建 # defaults 指定创建时或更新时的其他字段 obj, created = models.UserInfo.objects.update_or_create(username=‘root1‘, defaults={‘email‘: ‘1111111‘,‘u_id‘: 2, ‘t_id‘: 1})
根据主键查询 # models.UserInfo.objects.filter(id__in=[1,2,3]) # models.UserInfo.objects.in_bulk([1,2,3])
==========================补充1==========================select_related prefetch_related# q = models.UserInfo.objects.all()# select * from userinfo# select * from userinfo inner join usertype on ...# for row in q:# print(row.name,row.ut.title)
# select_related: 查询主动做连表# q = models.UserInfo.objects.all().select_related(‘ut‘,‘gp‘)# select * from userinfo# select * from userinfo inner join usertype on ...# for row in q:# print(row.name,row.ut.title)
# prefetch_related: 不做连表,做多次查询# q = models.UserInfo.objects.all().prefetch_related(‘ut‘)# select * from userinfo;# Django内部:ut_id = [2,4]# select * from usertype where id in [2,4]# for row in q:# print(row.id,row.ut.title)
# 多对多 # objs = [ # models.Boy(name=‘方少伟‘), # models.Boy(name=‘由秦兵‘), # models.Boy(name=‘陈涛‘), # models.Boy(name=‘闫龙‘), # models.Boy(name=‘吴彦祖‘), # ] # models.Boy.objects.bulk_create(objs,5) # # objss = [ # models.Girl(nick=‘小鱼‘), # models.Girl(nick=‘小周‘), # models.Girl(nick=‘小猫‘), # models.Girl(nick=‘小狗‘), # ] # models.Girl.objects.bulk_create(objss,5)
# models.Love.objects.create(b_id=1,g_id=1) # models.Love.objects.create(b_id=1,g_id=4) # models.Love.objects.create(b_id=2,g_id=4) # models.Love.objects.create(b_id=2,g_id=2)
# 1. 和方少伟有关系的姑娘 # obj = models.Boy.objects.filter(name=‘方少伟‘).first() # love_list = obj.love_set.all() # for row in love_list: # print(row.g.nick) # # # love_list = models.Love.objects.filter(b__name=‘方少伟‘) # for row in love_list: # print(row.g.nick) # # love_list = models.Love.objects.filter(b__name=‘方少伟‘).values(‘g__nick‘) # for item in love_list: # print(item[‘g__nick‘]) # # love_list = models.Love.objects.filter(b__name=‘方少伟‘).select_related(‘g‘) # for obj in love_list: # print(obj.g.nick)
第三章关系表 可以自己定义类 或者使用内置的生成,但是只能生成三列,两者合用 # m = models.ManyToManyField(‘Boy‘) 生成第三张关系表
#m = models.ManyToManyField(‘Girl‘,through="Love",through_fields=(‘b‘,‘g‘,)) 告诉django通过love连接,love表的b‘,‘g‘, 来关联 只提供查询和清空的功能
class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField(‘Girl‘,through="Love",through_fields=(‘b‘,‘g‘,))
class Girl(models.Model): nick = models.CharField(max_length=32) # m = models.ManyToManyField(‘Boy‘)
class Love(models.Model): b = models.ForeignKey(‘Boy‘) g = models.ForeignKey(‘Girl‘)#联合唯一索引 class Meta: unique_together = [ (‘b‘,‘g‘), ]
# obj = models.Boy.objects.filter(name=‘方少伟‘).first() # print(obj.id,obj.name) # obj.m.add(2) # obj.m.add(2,4) # obj.m.add(*[1,])
# obj.m.remove(1) # obj.m.remove(2,3) # obj.m.remove(*[4,])
# obj.m.set([1,])
# q = obj.m.all() # # [Girl对象] # print(q) # obj = models.Boy.objects.filter(name=‘方少伟‘).first() # girl_list = obj.m.all()
# obj = models.Boy.objects.filter(name=‘方少伟‘).first() # girl_list = obj.m.all() # girl_list = obj.m.filter(nick=‘小鱼‘) # print(girl_list)
# obj = models.Boy.objects.filter(name=‘方少伟‘).first() # obj.m.clear()
# obj = models.Girl.objects.filter(nick=‘小鱼‘).first() # print(obj.id,obj.nick) # v = obj.boy_set.all() # print(v)
编写ORM app01 -- models 中创建表ORM操作表:创建表修改表删除表操作数据行:增删改查ORM利用pymysql第三方工具连接数据库默认:SQLliteMySQL:mysql -> MySQLDB(修改django默认连接mySQL方式)
XSS 跨站脚本攻击 -慎用safe 和mark_safe(导入模块 )from django.utils.safestring import mark_safe
safe 在html中表明
-非要用,一定要过滤关键字
csrf 一般post提交的时候验证
FBv使用方法
a.基本应用 在form中添加 {% csrf_token %} {{ csrf_token }} 页面会显示随机字符串信息
b. 全局禁用setting中 ‘django.middleware.csrf.CsrfViewMiddleware‘, 注释
c. 局部禁用 全局使用,在函数上添加装饰器 from django.views.decorators.csrf import csrf_exempt
@csrf_exemptdef index():passd.局部使用全局禁用 在函数上添加装饰器
from django.views.decorators.csrf import csrf_protect
@csrf_protectdef index():pass
CBV使用装饰器方法from django.views import Viewfrom django.utils.decorators import method_decorator
# 1. CBV应用装饰器def wrapper(func): def inner(*args,**kwargs): return func(*args,**kwargs) return inner
# 1. 指定方法上添加装饰器
# class Foo(View): # # @method_decorator(csrf_protect) # def get(self,request): # pass # # def post(self,request): # pass
# 2. 在类上添加# @method_decorator(csrf_protect,name=‘dispatch‘) #cbv中所有的提交都会先到dispatch # class Foo(View):## def get(self,request):# pass## def post(self,request):# pass
Ajax提交数据时候,携带CSRF:a. 放置在data中携带<form method="POST" action="/csrf1.html">{% csrf_token %}<input id="user" type="text" name="user" /><input type="submit" value="提交"/><a onclick="submitForm();">Ajax提交</a></form><script src="/static/jquery-1.12.4.js"></script><script>function submitForm(){var csrf = $(‘input[name="csrfmiddlewaretoken"]‘).val();var user = $(‘#user‘).val();$.ajax({url: ‘/csrf1.html‘,type: ‘POST‘,data: { "user":user,‘csrfmiddlewaretoken‘: csrf},success:function(arg){console.log(arg);}})}
</script>b. 放在请求头中<form method="POST" action="/csrf1.html">{% csrf_token %}<input id="user" type="text" name="user" /><input type="submit" value="提交"/><a onclick="submitForm();">Ajax提交</a></form><script src="/static/jquery-1.12.4.js"></script><script src="/static/jquery.cookie.js"></script>
<script>function submitForm(){var token = $.cookie(‘csrftoken‘);var user = $(‘#user‘).val();$.ajax({url: ‘/csrf1.html‘,type: ‘POST‘,headers:{‘X-CSRFToken‘: token},data: { "user":user},success:function(arg){console.log(arg);}})}</script>
django视图 cbv 、 fbv
CBV先dispatch 判断method 反射如果想做定制化的 可以添加在这里
def dispatch(self, request, *args, **kwargs): print("before") obj=super(Login, self).dispatch(request,*args,**kwargs) print("after") return obj
url中设置re_path(‘classes/‘,views.Login.as_view),固定用法
view设置为form表单只有post 和 get 方法,ajex 支持所有from django.views import Viewclass Login(View): ‘‘‘ 请求方法基本常用的 get 查询 post 创建 put 更新 delete 删除 ‘‘‘
def dispatch(self, request, *args, **kwargs): print("before") obj=super(Login, self).dispatch(request,*args,**kwargs) print("after") return obj
def get(self,request): pass
def put(self,request): pass
django 分页操作分批获取数据models.UserInfo.objects.all()[0:10]models.UserInfo.objects.all()[10:20]
---django 自带提供的的分页
from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
def index(request): """ 分页 :param request: :return: """ # for i in range(300): # name = "root" + str(i) # models.UserInfo.objects.create(name=name,age=18,ut_id=1)
current_page = request.GET.get(‘page‘)
user_list = models.UserInfo.objects.all() paginator = Paginator(user_list,10) # per_page: 每页显示条目数量 # count: 数据总个数 # num_pages:总页数 # page_range:总页数的索引范围,如: (1,10),(1,200) # page: page对象 try: posts = paginator.page(current_page) except PageNotAnInteger as e: posts = paginator.page(1) except EmptyPage as e: posts = paginator.page(1) # has_next 是否有下一页 # next_page_number 下一页页码 # has_previous 是否有上一页 # previous_page_number 上一页页码 # object_list 分页之后的数据列表 # number 当前页 # paginator paginator对象 return render(request,‘index.html‘,{‘posts‘:posts})
--自定义分页组件
from utils.pager import PageInfodef custom(request): # 表示用户当前想要访问的页码: 8
all_count = models.UserInfo.objects.all().count()
page_info = PageInfo(request.GET.get(‘page‘),all_count,10,‘/custom.html‘,11) user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()]
return render(request,‘custom.html‘,{‘user_list‘:user_list,‘page_info‘:page_info})
class PageInfo(object):
def __init__(self,current_page,all_count,per_page,base_url,show_page=11): """
:param current_page: :param all_count: 数据库总行数 :param per_page: 每页显示函数 :return: """ try: self.current_page = int(current_page) except Exception as e: self.current_page = 1 self.per_page = per_page
a,b = divmod(all_count,per_page) if b: a = a +1 self.all_pager = a self.show_page = show_page self.base_url = base_url def start(self): return (self.current_page-1) * self.per_page
def end(self): return self.current_page * self.per_page
def pager(self): # v = "<a href=‘/custom.html?page=1‘>1</a><a href=‘/custom.html?page=2‘>2</a>" # return v page_list = []
half = int((self.show_page-1)/2)
# 如果数据总页数 < 11 if self.all_pager < self.show_page: begin = 1 stop = self.all_pager + 1 # 如果数据总页数 > 11 else: # 如果当前页 <=5,永远显示1,11 if self.current_page <= half: begin = 1 stop = self.show_page + 1 else: if self.current_page + half > self.all_pager: begin = self.all_pager - self.show_page + 1 stop = self.all_pager + 1 else: begin = self.current_page - half stop = self.current_page + half + 1
if self.current_page <= 1: prev = "<li><a href=‘#‘>上一页</a></li>" else: prev = "<li><a href=‘%s?page=%s‘>上一页</a></li>" %(self.base_url,self.current_page-1,) page_list.append(prev)
for i in range(begin,stop): if i == self.current_page: temp = "<li class=‘active‘><a href=‘%s?page=%s‘>%s</a></li>" %(self.base_url,i,i,) else: temp = "<li><a href=‘%s?page=%s‘>%s</a></li>" %(self.base_url,i,i,) page_list.append(temp)
if self.current_page >= self.all_pager: nex = "<li><a href=‘#‘>下一页</a></li>" else: nex = "<li><a href=‘%s?page=%s‘>下一页</a></li>" %(self.base_url,self.current_page+1,) page_list.append(nex)
return ‘‘.join(page_list)
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" /></head><body> <h1>用户列表</h1> <ul> {% for row in user_list %} <li>{{ row.name }}</li> {% endfor %} </ul>
<nav aria-label="Page navigation"> <ul class="pagination"> {{ page_info.pager|safe }} </ul> </nav></body></html>
以上是关于django学习之路的主要内容,如果未能解决你的问题,请参考以下文章