首页 > 代码库 > 框架----Django框架知识点整理
框架----Django框架知识点整理
一、cbv
1 cbv(class-base-view) 基于类的视图2 fbv(func-base-view) 基于函数的视图
a.基本演示
1 urlpatterns = [2 3 url(r‘^login.html$‘, views.Login.as_view()),4 ]
1 from django.views import View 2 3 class Login(View): 4 """ 5 get 查 6 post 创建 7 put 更新 8 delete 删除 9 """10 def dispatch(self, request, *args, **kwargs):11 print(‘before‘)12 obj = super(Login,self).dispatch(request,*args,**kwargs)13 print("after")14 return obj15 16 def get(self,request):17 return render(request,"login.html")18 19 def post(self,request):20 print(request.POST)21 22 return HttpResponse("Login.post")23 24 view.py
二、分页
a.Django分页
1 #浏览器访问2 http://127.0.0.1:8000/index.html/?page=9
1 urlpatterns = [2 3 #django分页4 url(r‘^index‘, views.index),5 ]
1 #django 分页 2 from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage 3 def index(request): 4 current_page = request.GET.get("page") 5 user_list = models.User_info.objects.all() 6 paginator = Paginator(user_list,10) #每页显示10条 7 8 """ 9 # count: 数据总个数10 # num_pages:总页数11 # page_range:总页数的索引范围,如: (1,10),(1,200)12 # page: page对象13 """14 try:15 posts = paginator.page(current_page) #当前页16 except PageNotAnInteger as e: #http://127.0.0.1:8000/index.html/?page=qqq 处理这种异常17 posts = paginator.page(1)18 except EmptyPage as e: #http://127.0.0.1:8000/index.html/?page=-10 捕获这种异常19 posts = paginator.page(1)20 21 22 """23 # has_next 是否有下一页24 # next_page_number 下一页页码25 # has_previous 是否有上一页26 # previous_page_number 上一页页码27 # object_list 分页之后的数据列表28 # number 当前页29 # paginator paginator对象30 """31 32 return render(request,"index.html",{"posts":posts})33 34 views.py
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <h1>用户列表</h1> 9 <ul>10 {% for row in posts.object_list %}11 <li>{{ row.name }}</li>12 {% endfor %}13 </ul>14 <div>15 {% if posts.has_previous %}16 <a href="/index.html/?page={{ posts.previous_page_number }}">上一页</a>17 {% endif %}18 19 {% for num in posts.paginator.page_range %}20 <a href="/index.html/?page={{ num }}">{{ num }}</a>21 {% endfor %}22 23 {% if posts.has_next %}24 <a href="/index.html/?page={{ posts.next_page_number }}">下一页</a>25 {% endif %}26 </div>27 28 </body>29 </html>30 31 index.html
b.自定义分页
1 #浏览器访问2 http://127.0.0.1:8000/custom/?page=6
1 urlpatterns = [2 3 #自定义分页4 url(r‘^custom/‘, views.custom),5 ]
1 from utils.pager import PageInfo 2 #自定义分页 3 def custom(request): 4 5 #总页数 6 all_count = models.User_info.objects.all().count() 7 8 #用户当前想要访问的页码 9 current_page = request.GET.get("page")10 page_info = PageInfo(current_page,all_count,10,"/custom",11)11 12 user_list = models.User_info.objects.all()[page_info.start():page_info.end()]13 14 return render(request,"custom.html",{"user_list":user_list,"page_info":page_info})15 16 views.py
1 class PageInfo(object): 2 3 def __init__(self,current_page,all_count,per_page,base_url,show_page=11): 4 5 #如果传值错误进入第一页 6 try: 7 self.current_page = int(current_page) 8 except Exception as e: 9 self.current_page = 110 self.per_page = per_page #每页显示的个数11 12 13 a,b = divmod(all_count,per_page) #页数 余数14 if b:15 a = a + 116 self.all_page = a #总页码17 self.show_page = show_page18 self.base_url = base_url19 20 def start(self):21 # 1 0: 1022 # 2 10:2023 # 3 20:3024 return (self.current_page-1) * self.per_page25 26 def end(self):27 return self.current_page * self.per_page28 29 def pager(self):30 31 page_list = []32 33 half = int((self.show_page-1)/2)34 35 if self.all_page < self.show_page:36 begin = 137 stop = self.all_page + 138 else:39 if self.current_page < half:40 begin = 141 stop = self.show_page + 142 else:43 if self.current_page + half > self.all_page:44 begin = self.all_page - 10 +145 stop = self.all_page + 146 else:47 begin = self.current_page - half48 stop = self.current_page + half +149 50 if self.current_page <=1:51 prev = "<li><a href=http://www.mamicode.com/‘#‘>上一页"52 else:53 prev = "<li><a href=http://www.mamicode.com/‘%s/?page=%s‘>上一页"%(self.base_url,self.current_page - 1)54 55 page_list.append(prev)56 57 58 59 for i in range(begin,stop):60 if i == self.current_page:61 temp = "<li class=‘active‘><a href=http://www.mamicode.com/‘/custom/?page=%s‘>%s"%(i,i)62 else:63 temp = "<li><a href=http://www.mamicode.com/‘%s/?page=%s‘>%s"%(self.base_url,i,i)64 page_list.append(temp)65 66 67 if self.current_page >= self.all_page:68 nex = "<li><a href=http://www.mamicode.com/‘#‘>下一页"69 else:70 nex = "<li><a href=http://www.mamicode.com/‘%s/?page=%s‘>下一页" % (self.base_url,self.current_page + 1)71 72 page_list.append(nex)73 74 return "".join(page_list)75 76 utils/pager.py
1 from django.db import models 2 3 # Create your models here. 4 5 6 class User_type(models.Model): 7 uid = models.BigAutoField(primary_key=True) 8 title = models.CharField(max_length=32) 9 10 class User_info(models.Model):11 name = models.CharField(max_length=32)12 age = models.CharField(max_length=32)13 ut = models.ForeignKey("User_type")14 15 models.py
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" /> 7 </head> 8 <body> 9 10 {% for row in user_list %}11 <li>{{ row.name }}</li>12 {% endfor %}13 14 15 <nav aria-label="Page navigation">16 <ul class="pagination">17 {{ page_info.pager |safe }}18 19 </ul>20 </nav>21 </body>22 </html>23 24 custom.html
三、ORM正反向连表操作
1 #ORM正反向连表操作 2 - models 3 from django.db import models 4 5 class Foo(models.Model): 6 """ 7 第三个表 8 """ 9 caption = models.CharField(max_length=16)10 11 12 class UserType(models.Model):13 """14 用户类型15 """16 title = models.CharField(max_length=32)17 fo = models.ForeignKey(‘Foo‘)18 19 20 class UserInfo(models.Model):21 """22 用户表23 """24 name = models.CharField(max_length=16)25 age = models.IntegerField()26 ut = models.ForeignKey(‘UserType‘)27 28 29 - views30 ----#跨表(正向操作)---UserInfo----含ForeignKey字段 PS: 一个用户只有一个用户类型31 # 获取32 # QuerySet[obj,obj,obj]33 result = models.UserInfo.objects.all()34 for obj in result:35 print(obj.name,obj.age,obj.ut_id,obj.ut.title,obj.ut.fo.caption)36 37 ----#跨表(反向操作)---UserType----不含ForeignKey字段 PS: 一个用户类型下可以有很多用户38 39 obj = models.UserType.objects.all().first()40 print(‘用户类型‘,obj.id,obj.title)41 for row in obj.userinfo_set.all(): #使用的是与之关联的表名小写加_set.all()这个方法取到所有东西42 print(row.name,row.age)
四、数据获取多个数据时(注意3种情况的不同之处<跨表查询、跨表取值>)
1 # 数据获取多个数据时(注意3种情况的不同之处<跨表查询、跨表取值>) 2 1. [obj,obj,obj,] # .all()和.filter()拿到的结果是QuerySet对象 3 models.UserInfo.objects.all() 4 models.UserInfo.objects.filter(id__gt=1) 5 result = models.UserInfo.objects.all() 6 for item in result: 7 print(item.name,item.ut.title) # 取值方式:item.name,item.ut.title 可以跨表 8 9 10 2. [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},] # .values()拿到的结果是字典11 models.UserInfo.objects.all().values(‘id‘,‘name‘)12 models.UserInfo.objects.filter(id__gt=1).values(‘id‘,‘name‘)13 #无法跨表14 result = models.UserInfo.objects.all().values(‘id‘,‘name‘)15 for item in result:16 print(item[‘id‘],item[‘name‘]) # 取值方式:item[‘id‘],item[‘name‘] #无法跨表 17 #跨表 使用__(双下划线)18 result = models.UserInfo.objects.all().values(‘id‘,‘name‘,"ut__title") # 这里查询时跨表使用的是ut__title 双下划线19 for item in result:20 print(item[‘id‘],item[‘name‘],item[‘ut__title‘]) # 跨表取值时也用的是双下滑线__21 22 23 24 3. [(1,df),(2,‘df‘)] # .values_list()拿到的结果是元组25 models.UserInfo.objects.all().values_list(‘id‘,‘name‘)26 models.UserInfo.objects.filter(id__gt=1).values_list(‘id‘,‘name‘)27 #无法跨表28 result = models.UserInfo.objects.all().values_list(‘id‘,‘name‘)29 for item in result:30 print(item[0],item[1]) # 取值方式: item[0],item[1] #无法跨表31 #跨表 使用__(双下划线)32 result = models.UserInfo.objects.all().values_list(‘id‘,‘name‘,"ut__title") # 这里要跨表使用的是ut__title 双下划线33 for item in result:34 print(item[0],item[1],item[2]) # 跨表取值时用的是下标
五、CSRF(跨站请求伪造)
CSRF(Cross-site request forgery)跨站请求伪造,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS) 但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。 理解:csrf_token防止从别的网站向自己网站发post请求, 客户来访问网站,网站会向客户发送随机字符串,然后客户带随机字符串发送post请求 只有带随机字符串来,网站才认,一般是post请求才要求带随机字符串,其它网站第一次来不会带随机字符串。
a. django开启csrf
MIDDLEWARE = [ ‘django.middleware.csrf.CsrfViewMiddleware‘,]
b.HTML中使用
{% csrf_token %} #只要写上{% csrf_token %} 会有一个隐藏的input随机字符串,在cookie也有一个随机的字符串,form表单提交数据时,一般会使用{{ csrf_token }} #生成随机的字符串
c.django中设置防跨站请求伪造功能有分为全局和局部
#局部 from django.views.decorators.csrf import csrf_exempt,csrf_protect @csrf_protect settings中没有设置全局中间件,为当前函数强制设置防跨站请求伪造功能。@csrf_exempt settings中设置了全局中间件,取消当前函数防跨站请求伪造功能。
1 #fbv 2 3 @csrf_protect 4 def func(object): 5 pass 6 7 #cbv 8 9 from django.views import View10 from django.utils.decorators import method_decorator11 12 @method_decorator(csrf_exempt,name="dispatch")13 class foo(View)14 pass15 16 fbv和cbv应用装饰器
1 #方式一 类上加装饰器: 2 3 def wrapper(func): 4 def inner(*args,**kwargs): 5 return func(*args,**kwargs) 6 return inner 7 8 @method_decorator(wrapper,name="get") 9 @method_decorator(wrapper,name="post")10 class foo(View):11 12 def get(self,request):13 pass14 15 def post(self,request):16 pass17 18 19 20 #方式二 类上“dispatch”加装饰器:21 22 def wrapper(func):23 def inner(*args,**kwargs):24 return func(*args,**kwargs)25 return inner26 27 @method_decorator(wrapper,name="dispatch")28 class foo(View):29 30 def dispatch(self,request,*args,**kwargs):31 return xxx32 33 def get(self,request):34 pass35 36 def post(self,request):37 pass38 39 40 #方式三 方法上加装饰器:41 42 def wrapper(func):43 def inner(*args,**kwargs):44 return func(*args,**kwargs)45 return inner46 47 class foo(View):48 49 50 @method_decorator(wrapper)51 def get(self,request):52 pass53 54 def post(self,request):55 pass56 57 cbv应用其它装饰器
d. Ajax提交数据 携带CSRF
1. 通过获取隐藏的input标签中的字符串,放置在data中发送
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <form method="POST" action="/csrf1.html"> 9 {% csrf_token %}10 <input id="user" type="text" name="user"/>11 <a onclick="submitForm();">Ajax提交</a>12 </form>13 14 <script src="/static/jquery-1.12.4.js"></script>15 <script>16 function submitForm() {17 var csrf = $(‘input[name="csrfmiddlewaretoken"]‘).val();18 var user = $("#user").val();19 $.ajax({20 url:‘/csrf1.html‘,21 type:‘POST‘,22 data:{"user":user,"csrfmiddlewaretoken":csrf},23 success:function (arg) {24 console.log(arg);25 }26 27 })28 }29 </script>30 31 32 33 </body>34 </html>35 36 csrf1.html
1 urlpatterns = [2 3 url(r‘^csrf1.html‘, views.csrf1),4 ]
1 def csrf1(request):2 3 if request.method == ‘GET‘:4 return render(request,‘csrf1.html‘)5 else:6 return HttpResponse(‘ok‘)
2. 通过获取返回的cookie中的字符串,放置在请求头中发送
通过在console中 document.cookie可以获取 csrftoken=JPv1gIdrBiAlK2RCrgFs0OKwsncPXvwPfMhEWIVzMdMFymIayiuGu2GkBAu57moL但需要切割字符串,通过引入jquery.cookie.js对cookie操作,使用$.cookie("csrftoken")
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <form method="POST" action="/csrf1.html"> 9 {% csrf_token %}10 <input id="user" type="text" name="user"/>11 <a onclick="submitForm();">Ajax提交</a>12 </form>13 14 <script src="/static/jquery-1.12.4.js"></script>15 <script src="/static/jquery.cookie.js"></script>16 <script>17 function submitForm() {18 var token = $.cookie("csrftoken");19 var user = $("#user").val();20 $.ajax({21 url:‘/csrf1.html‘,22 type:‘POST‘,23 headers:{"X-CSRFToken":token},24 data:{"user":user},25 success:function (arg) {26 console.log(arg);27 }28 29 })30 }31 </script>32 33 34 35 36 37 </body>38 </html>39 40 csrf1.html
六、Django框架最最最最最最基础的3+5基本使用步骤 ?????
1,创建项目文件夹 在终端Terminal执行命令: django-admin startproject 项目名 2,配置3个地方 (1)模板路径配置 TEMPLATES = [ { ‘BACKEND‘: ‘django.template.backends.django.DjangoTemplates‘, ‘DIRS‘: [os.path.join(BASE_DIR,‘templates‘)], # 这一步 ‘APP_DIRS‘: True, ‘OPTIONS‘: { ‘context_processors‘: [ ‘django.template.context_processors.debug‘, ‘django.template.context_processors.request‘, ‘django.contrib.auth.context_processors.auth‘, ‘django.contrib.messages.context_processors.messages‘, ], }, }, ] (2) 静态文件配置 STATIC_URL = ‘/static/‘ STATICFILES_DIR = ( os.path.join(BASE_DIR,‘static‘) ) (3) # ‘django.middleware.csrf.CsrfViewMiddleware‘, 注释这一行 3,Django框架5步 在终端Terminal执行命令创建app模块: python manage.py startapp 模块名 (1)连接数据库 DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.mysql‘, ‘NAME‘: "studentPro", ‘USER‘:‘yangzai‘, ‘PASSWORD‘:‘Oldsyang=5201314@yangzai‘, ‘HOST‘:‘mypy.me‘, ‘PORT‘:3306, } } (2)导入pymysql 在__init__中写入 import pymysql pymysql.install_as_MySQLdb() (3)创建model from django.db import models class UserInfo(models.Model): id = name = password = (4)注册模块 INSTALLED_APPS = [ ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘app01‘ -----这一步 ] (5)初始化数据库 python manage.py makemigrations --先执行 python manage.py migrate --后执行
七、Django框架里面return的3种返回
return render() - 返回页面 - return render(request,‘index.html‘,{‘std_list‘:std_list}) 3个参数含义: request:用户的请求信息 ‘index.html‘:需要返回的模板html页面 {‘std_list‘:std_list}:存放模板文件里面要被替换的占位符所对应的值 return HttpResponse() - 返回字符串 - return HttpResponse(json.dumps(ret)) return redirect() - 返回url请求 - return redirect(‘/teachers/‘) 提示点:redirect,href,action,这3中url请求,都要在地址前加/斜杠 例子:return redirect(‘/classes.html‘) <a href=http://www.mamicode.com/"/edit_class/{{ row.id }}.html"> <form method="POST" action="/edit_class/{{ id }}.html">return的3中返回
八、cookie
a. 简单应用
1 def login(request): 2 if request.method=="GET": 3 return render(request,"login.html") 4 else: 5 name = request.POST.get("name") 6 password = request.POST.get("password") 7 if name == "alex" and password == "123": 8 obj = redirect("/classes/") 9 obj.set_cookie("ticket","123456",max_age=10)10 return obj11 else:12 return redirect("/login/")13 14 15 16 def classes(request):17 sk = request.COOKIES18 print(sk)19 if not sk:20 return redirect("/login/")
b. 过期时间的两种格式
1 方式一: 2 obj.set_cookie("ticket","123456",max_age=10) 3 4 方式二: 5 import datetime 6 from datetime import timedelta #时间的加减 7 ct = datetime.datetime.utcnow() #获取当前日期 8 v= timedelta(seconds=10) #10秒 9 value = http://www.mamicode.com/ct + v10 11 obj.set_cookie("ticket","123456",expires=value)
c. 限制路径
1 obj.set_cookie("ticket","123456",max_age=10,path="/") #所有路径都可以访问2 3 obj.set_cookie("ticket","123456",max_age=10,path="/class") #只有class访问
d. cookie签名
1 #加2 obj.set_signed_cookie("ticket","123456",salt="abc")3 4 #解5 sk = request.get_signed_cookie("ticket",salt="abc")
九、session
1 流程:客户登录网址,验证成功后,服务端生成一个随机字符串和随机字符串对应的键值,然后把随机字符串通过cookie发送给客户端2 客户端拿着随机字符串通过cookir再次登陆,服务端拿着随机字符串和保存在本地的数据对应,以确定用户的登录状态
Cookie是什么? 保存在客户端浏览器上的键值对Session是什么? 保存在服务端的数据(本质是键值对) { “aaaaa":{‘id‘:1,‘name‘:‘于浩‘,email=‘xxxx‘} "bbbbb":{‘id‘:2,‘name‘:‘陈涛‘,email=‘0000‘} } 应用:依赖cookie 作用:保持会话(Web网站) 好处:敏感信息不会直接给客户端 梳理: 1. 保存在服务端的数据(本质是键值对) 2. 配置文件中: - 存储位置 - 超时时间、每次刷新更新时间
a. 简单示例
用户访问http://127.0.0.1:8000/login/
urlpatterns = [ url(r‘^index/‘, views.index), url(r‘^login/‘, views.login),]
1 def login(request): 2 if request.method == ‘GET‘: 3 return render(request,‘login.html‘) 4 else: 5 u = request.POST.get(‘user‘) 6 p = request.POST.get(‘pwd‘) 7 obj = models.UserAdmin.objects.filter(username=u,password=p).first() 8 if obj: 9 # 1. 生成随机字符串10 # 2. 通过cookie发送给客户端11 # 3. 服务端保存12 # {13 # 随机字符串1: {‘username‘:‘alex‘,‘email‘:x‘‘...}14 # }15 request.session[‘username‘] = obj.username16 return redirect(‘/index/‘)17 else:18 return render(request,‘login.html‘,{‘msg‘:‘用户名或密码错误‘})19 20 21 def index(request):22 # 1. 获取客户端端cookie中的随机字符串23 # 2. 去session中查找有没有随机字符24 # 3. 去session对应key的value中查看是否有 username25 v = request.session.get(‘username‘)26 if v:27 return HttpResponse(‘登录成功:%s‘ %v)28 else:29 return redirect(‘/login/‘)30 31 views.py
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 9 <form action="/login/" method="POST">10 <input type="text" name="user">11 <input type="text" name="pwd">12 <input type="submit" value="提交">{{ msg }}13 </form>14 15 16 </body>17 </html>18 19 login.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 9 <h1>index page</h1>10 11 </body>12 </html>13 14 index.html
十、URL(路由配置系统)
1 URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码<br>对于那个URL调用那段代码 2 3 urlpatterns = [ 4 url(正则表达式, views视图函数,参数,别名), 5 ] 6 7 参数说明: 8 9 一个正则表达式字符串10 一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串11 可选的要传递给视图函数的默认参数(字典形式)12 一个可选的name参数
1. 单一路由对应
1 url(r‘^index$‘, views.index)
2. 基于正则的路由
1 # $2 url(r‘^index/(\d{4})$‘,views.index)3 4 #无命名分组5 url(r‘^index/(\d{4})/(\d{2})‘,views.index)6 7 #有命名分组8 url(r‘^index/(?P<year>\d{4})/(?P<month>\d{2})‘,views.index)
1 ############################无命名 2 3 #-----------------() 相当于传参数 4 5 url(r‘^index/(\d{4})‘,views.index) 6 7 def index(request,arg): 8 return HttpResponse(arg) 9 10 #url访问http://127.0.0.1:8000/index/111311 12 #-----------------() 接受两个参数13 14 url(r‘^index/(\d{4})/(\d{2})‘,views.index)15 16 def index(request,arg,arg1):17 return HttpResponse("year: %s month: %s"%(arg,arg1))18 19 #url访问http://127.0.0.1:8000/index/2017/0620 year: 2017 month: 0621 22 23 24 ############################有命名25 url(r‘^index/(?P<year>\d{4})/(?P<month>\d{2})‘,views.index)26 27 def index(request,year,month):28 return HttpResponse("year: %s month: %s"%(year,month))29 30 #url访问http://127.0.0.1:8000/index/2017/0631 year: 2017 month: 0632 33 有无命名分组 演示
3. 为路由映射设置名称
1 #应用一:2 url(r‘^index‘,views.index,name="arg")3 4 {{ url "arg" }} 匹配index5 {{ url "arg" i}}6 7 #应用二:8 reverse反向获取url
1 ##############根据url反生成名字 2 from django.shortcuts import reverse 3 4 url(r‘^index‘,views.index,name="arg") 5 6 def index(request): 7 v = reverse("arg") 8 print(v) 9 return HttpResponse()10 11 #用户访问http://127.0.0.1:8000/index12 /index13 14 15 ##############根据url改变url16 17 url(r‘^index/(\d+)/‘,views.index,name="n1")18 19 def index(request,xx):20 21 v = reverse(‘n1‘,args=(1,))22 print(v)23 return HttpResponse("...")24 25 #访问http://127.0.0.1:8000/index/222/26 /index/1/27 28 reverse示例 演示
4. 路由分发
1 url(r‘^app01/‘,include("app01.urls"))2 url(r‘^app02/‘,include("app02.urls"))3 4 #没有匹配成功,返回默认页面5 url(r‘^‘,include("views.default"))
十一、Model
a. 创建表
1 from django.db import models 2 3 4 class User_type(models.Model): 5 uid = models.BigAutoField(primary_key=True) 6 title = models.CharField(max_length=32) 7 8 class User_info(models.Model): 9 name = models.CharField(max_length=32)10 age = models.CharField(max_length=32)11 ut = models.ForeignKey("User_type")12 13 14 python3 manage.py makemigrations15 16 python3 manage.py migrate17 18 19 ---------------------其它---------------------20 21 class part(models.Model):22 cid = models.BigAutoField(primary_key=True)23 title = models.CharField(max_length=32,null=False)24 25 26 class student(models.Model):27 sid = models.BigAutoField(primary_key=True)28 name = models.CharField(max_length=32,null=False)29 pub_data=http://www.mamicode.com/models.DateField()30 age = models.IntegerField(default=18)31 # 新增加的列 如果原先表里有值,写default32 ug = models.ForeignKey("part",null=True) #如果新增加外键,加null=True
b. ORM操作
1 #增 2 # models.User_type.objects.create(title="黑金用户") 3 4 # obj = models.User_type(title="小白用户") 5 # obj.save() 6 7 8 #删 9 #models.User_type.objects.filter(title="小白用户").delete() # 删除指定条件的数据10 11 #改12 #models.User_type.objects.filter(title="黑金用户").update(title="黑卡用户") # 修改指定条件的数据13 14 #查15 # models.User_type.objects.get(title="大白用户") # 获取单条数据,不存在则报错(不建议)16 # models.User_type.objects.all() # 获取全部17 # models.User_type.objects.filter(title="小白用户") # 获取指定条件的数据18 # models.User_type.objects.exclude(title="黄金用户") # 排除指定条件的数据19 20 基本增删改查
1 # 获取个数 2 3 models.User_info.objects.filter(age=18).count() 4 5 6 # 大于 小于 7 8 # models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值 9 # models.Tb1.objects.filter(id__gte=1) # 获取id大于等于1的值10 # models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值11 # models.Tb1.objects.filter(id__lte=10) # 获取id小于10的值12 # models.Tb1.objects.filter(id__gt=1,id__lt=10) # 获取id大于1 且 小于10的值13 14 15 16 #in17 18 models.User_info.objects.filter(age__in=[19]) # in 19 models.User_info.objects.exclude(age__in=[19]) # not in20 21 22 # isnull23 24 models.User_info.objects.filter(age__isnull=True) # age列为不为空25 models.User_info.objects.filter(age__isnull=False) # age列是不是 不为空26 27 28 # contains29 30 # models.Tb1.objects.filter(name__contains="ven")31 # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感32 # models.Tb1.objects.exclude(name__icontains="ven")33 34 35 36 # range37 38 # models.Tb1.objects.filter(id__range=[1, 5]) # 范围bettwen and39 40 41 #开始 结束42 43 # startswith,istartswith, endswith, iendswith44 45 46 47 #order_by 48 49 #models.User_info.objects.all().order_by("id") # asc50 #models.User_info.objects.all().order_by("-id") # desc51 52 # models.Tb1.objects.filter(name=‘seven‘).order_by(‘id‘) # asc53 # models.Tb1.objects.filter(name=‘seven‘).order_by(‘-id‘) # desc54 55 56 57 #group by #后面出现filter代表having58 59 from django.db.models import Count60 #models.User_info.objects.values("name","age").annotate() #没有起作用61 #SELECT "app01_user_info"."name", "app01_user_info"."age" FROM "app01_user_info"62 63 #models.User_info.objects.values("age").annotate(xxx=Count("age"))64 #SELECT "app01_user_info"."age", COUNT("app01_user_info"."age") AS "xxx" FROM "app01_user_info" GROUP BY "app01_user_info"."age"65 66 #models.User_info.objects.values("age").annotate(xxx=Count("age")).filter(xxx__gt=2) #年龄相同次数大于2的查出来67 #SELECT "app01_user_info"."age", COUNT("app01_user_info"."age") AS "xxx" FROM "app01_user_info" GROUP BY "app01_user_info"."age" HAVING COUNT("app01_user_info"."age") > 268 69 70 #注意两次filter 第一次代表where 第二次代表having71 72 #models.User_info.objects.filter(id__gt=2).values("age").annotate(xxx=Count("age")).filter(xxx__gt=2) 73 #SELECT "app01_user_info"."age", COUNT("app01_user_info"."age") AS "xxx" FROM "app01_user_info" WHERE "app01_user_info"."id" > 2 GROUP BY "app01_user_info"."age" HAVING COUNT("app01_user_info"."age") > 274 75 常用方法
1 # F 2 3 # from django.db.models import F 4 # models.User_info.objects.all().update(age=F("age")+5) # age列加5 5 6 7 # Q 8 9 # 方式一:10 # Q(nid__gt=10)11 # Q(nid=8) | Q(nid__gt=10)12 # Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption=‘root‘)13 14 15 #-------------------------------以下三种查找方式相同效果16 17 # obj = models.User_info.objects.filter(id=307,name="egon")18 19 # condition ={20 # ‘id‘:307,21 # ‘name‘:‘egon‘,22 # }23 # obj = models.User_info.objects.filter(**condition)24 25 #obj = models.User_info.objects.filter(Q(id=307) & Q(name="egon"))26 ---------------------------------27 28 29 # 方式二:30 31 32 # q1 = Q()33 # q1.connector = ‘OR‘34 # q1.children.append((‘id‘, 1))35 # q1.children.append((‘id‘, 10))36 # q1.children.append((‘id‘, 9))37 38 # q2 = Q()39 # q2.connector = ‘OR‘40 # q2.children.append((‘c1‘, 1))41 # q2.children.append((‘c1‘, 10))42 # q2.children.append((‘c1‘, 9))43 44 # q3 = Q()45 # q3.connector = ‘AND‘46 # q3.children.append((‘id‘, 1))47 # q3.children.append((‘id‘, 2))48 # q1.add(q3, ‘OR‘)49 50 # con = Q()51 # con.add(q1, ‘AND‘)52 # con.add(q2, ‘AND‘)53 54 #(id=1 or id=10 or id=9 or (id=1 and id=2)) and (c1=1 or c1=10 or c1=9) #等于上面55 56 # models.Tb1.objects.filter(con)57 58 59 # Q演示60 condition_dict = {61 ‘k1‘:[1,2,3,4],62 ‘k2‘:[1,],63 ‘k3‘:[11,]64 }65 66 con = Q()67 for k,v in condition_dict.items():68 q = Q()69 q.connector = ‘OR‘70 for i in v:71 q.children.append((‘id‘,1))72 con.add(q,‘AND‘)73 74 models.User_info.objects.filter(con)75 76 F Q 演示
c. 多对多操作
方式一:通过外键创建第三张表
1 class Boy(models.Model): 2 name = models.CharField(max_length=32) 3 4 class Girl(models.Model): 5 nick = models.CharField(max_length=32) 6 7 class Love(models.Model): 8 b = models.ForeignKey("Boy") 9 g = models.ForeignKey("Girl")10 11 class Meta:12 unique_together = [13 ("b","g"),14 ]
1 #表里插入数据 2 3 objs = [ 4 models.Boy(name=‘方少伟‘), 5 models.Boy(name=‘游勤斌‘), 6 models.Boy(name=‘于浩‘), 7 models.Boy(name=‘陈涛‘), 8 ] 9 models.Boy.objects.bulk_create(objs,4)10 11 result = [12 models.Girl(nick=‘于浩姐姐‘),13 models.Girl(nick=‘景甜‘),14 models.Girl(nick=‘刘亦非‘),15 models.Girl(nick=‘苍老师‘),16 ]17 models.Girl.objects.bulk_create(result, 4)18 19 models.Love.objects.create(b_id=1,g_id=1)20 models.Love.objects.create(b_id=1,g_id=2)21 models.Love.objects.create(b_id=1,g_id=3)22 models.Love.objects.create(b_id=2,g_id=4)23 24 25 ################### 查找和我有关系的女孩 四种方式 ################26 27 28 obj = models.Boy.objects.filter(name="方少伟").first()29 love_list = obj.love_set.all()30 for row in love_list:31 print(row.g.nick)32 33 love_list = models.Love.objects.filter(b__name="方少伟")34 for row in love_list:35 print(row.g.nick)36 37 38 #下面两个效果好39 40 love_list = models.Love.objects.filter(b__name="方少伟").values("g__nick")41 for item in love_list:42 print(item["g__nick"]) 43 44 45 46 love_list = models.Love.objects.filter(b__name="方少伟").select_related("g")47 for obj in love_list:48 print(obj.g.nick)49 50 SQL演示
方式二:通过 ManyToManyField 创建第三张表
1 class Boy(models.Model):2 name = models.CharField(max_length=32)3 m = models.ManyToManyField("Girl")4 5 class Girl(models.Model):6 nick = models.CharField(max_length=32)
1 obj = models.Boy.objects.filter(name="方少伟").first() 2 # print(obj.id,obj.name) 3 4 # obj.m.add(2) 5 # obj.m.add(1,3) 6 # obj.m.add(*[4,]) 7 8 # obj.m.remove(2) 9 # obj.m.remove(1,3)10 # obj.m.remove(*[4,])11 12 # obj.m.set([1,4,])13 14 15 # girl_list = obj.m.all()16 # girl_list = obj.m.filter(nick="苍老师")17 18 19 # obj.m.clear()20 21 obj = models.Girl.objects.filter(nick="苍老师").first()22 v = obj.boy_set.all() 23 24 SQL 演示
方式三:通过 外键 和 ManyToManyField 创建
1 class Boy(models.Model): 2 name = models.CharField(max_length=32) 3 m = models.ManyToManyField("Girl",through="Love",through_fields=("b","g",)) 4 5 class Girl(models.Model): 6 nick = models.CharField(max_length=32) 7 8 class Love(models.Model): 9 b = models.ForeignKey("Boy")10 g = models.ForeignKey("Girl")11 12 class Meta:13 unique_together = [14 ("b","g"),15 ]
1 obj = models.Boy.objects.filter(name="方少伟").first()2 3 #只可以查或清空4 obj.m.clear()5 6 obj.m.all()7 8 SQL 操作
d. 一对多
1 正向: 2 filter() values,values_list() -> 跨表 fk__xxx 3 objs = all() 4 for obj in objs: 5 obj.fk. 6 反向: 7 filter() values,values_list() -> 跨表 表名称__xxx 8 objs = all() 9 for obj in objs:10 obj.表名称_set.all()
1.连表操作演示
1 urlpatterns = [2 3 url(r‘^test/‘, views.test),4 5 ]
1 class User_type(models.Model): 2 uid = models.BigAutoField(primary_key=True) 3 title = models.CharField(max_length=32) 4 5 class User_info(models.Model): 6 name = models.CharField(max_length=32) 7 age = models.CharField(max_length=32) 8 ut = models.ForeignKey("User_type") 9 10 models.py
1 def test(request): 2 models.User_type.objects.create(title="普通用户") 3 models.User_type.objects.create(title="白金用户") 4 models.User_type.objects.create(title="黄金用户") 5 6 7 models.User_info.objects.create(name="小鸡",age=18,ut_id=1) 8 models.User_info.objects.create(name="小狗",age=18,ut_id=2) 9 models.User_info.objects.create(name="小猫",age=18,ut_id=2)10 models.User_info.objects.create(name="小雨",age=18,ut_id=3)11 models.User_info.objects.create(name="大雨",age=18,ut_id=1)12 13 for i in range(300):14 name = "root" + str(i)15 models.User_info.objects.create(name=name, age=18, ut_id=1)16 17 #正向操作18 obj = models.User_info.objects.all().first()19 print(obj.name,obj.age,obj.ut.title)20 21 #反向操作 obj.表名小写_set.all()22 obj = models.User_type.objects.all().first()23 for row in obj.user_info_set.all():24 print(row.name,row.age)25 26 result = models.User_type.objects.all()27 for item in result:28 print(item.title,item.user_info_set.all())29 print(item.user_info_set.filter(name="小雨"))30 31 32 #字典格式33 result = models.User_info.objects.all().values("id","name")34 for row in result:35 print(row)36 37 #字典格式查的时候跨表38 result = models.User_info.objects.all().values("id","name","ut__title")39 for row in result:40 print(row["id"],row["name"],row["ut__title"])41 42 43 44 45 46 # 元组格式47 # result = models.User_info.objects.all().values_list("id","name")48 # for row in result:49 # print(row)50 51 return HttpResponse(".....")52 53 views.py
十二、ORM操作
1 操作数据行:---------(在views中操作) 2 增 3 models.Tb1.objects.create(c1=‘xx‘, c2=‘oo‘) 增加一条数据,可以接受字典类型数据 **kwargs 4 obj = models.Tb1(c1=‘xx‘, c2=‘oo‘) 5 obj.save() 6 7 删 8 models.Tb1.objects.filter(name=‘seven‘).delete() # 删除指定条件的数据 9 10 改11 models.Tb1.objects.filter(name=‘seven‘).update(gender=‘0‘) # 将指定条件的数据更新,均支持 **kwargs12 obj = models.Tb1.objects.get(id=1)13 obj.c1 = ‘111‘14 obj.save() # 修改单条数据15 16 查17 models.Tb1.objects.get(id=123) # 获取单条数据,不存在则报错(不建议)18 models.Tb1.objects.all() # 获取全部19 models.Tb1.objects.filter(name=‘seven‘) # 获取指定条件的数据
1 # 获取个数 2 # 3 # models.Tb1.objects.filter(name=‘seven‘).count() 4 5 # 大于,小于 6 # 7 # models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值 8 # models.Tb1.objects.filter(id__gte=1) # 获取id大于等于1的值 9 # models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值10 # models.Tb1.objects.filter(id__lte=10) # 获取id小于10的值11 # models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值12 13 # in14 #15 # models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据16 # models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in17 18 # isnull19 # Entry.objects.filter(pub_date__isnull=True)20 21 # contains22 #23 # models.Tb1.objects.filter(name__contains="ven")24 # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感25 # models.Tb1.objects.exclude(name__icontains="ven")26 27 # range28 #29 # models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and30 31 # 其他类似32 #33 # startswith,istartswith, endswith, iendswith,34 35 # order by36 #37 # models.Tb1.objects.filter(name=‘seven‘).order_by(‘id‘) # asc38 # models.Tb1.objects.filter(name=‘seven‘).order_by(‘-id‘) # desc39 40 # group by41 #42 # from django.db.models import Count, Min, Max, Sum43 # models.Tb1.objects.filter(c1=1).values(‘id‘).annotate(c=Count(‘num‘))44 # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"45 46 # limit 、offset47 #48 # models.Tb1.objects.all()[10:20]49 50 # regex正则匹配,iregex 不区分大小写51 #52 # Entry.objects.get(title__regex=r‘^(An?|The) +‘)53 # Entry.objects.get(title__iregex=r‘^(an?|the) +‘)54 55 # date56 #57 # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))58 # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))59 60 # year61 #62 # Entry.objects.filter(pub_date__year=2005)63 # Entry.objects.filter(pub_date__year__gte=2005)64 65 # month66 #67 # Entry.objects.filter(pub_date__month=12)68 # Entry.objects.filter(pub_date__month__gte=6)69 70 # day71 #72 # Entry.objects.filter(pub_date__day=3)73 # Entry.objects.filter(pub_date__day__gte=3)74 75 # week_day76 #77 # Entry.objects.filter(pub_date__week_day=2)78 # Entry.objects.filter(pub_date__week_day__gte=2)79 80 # hour81 #82 # Event.objects.filter(timestamp__hour=23)83 # Event.objects.filter(time__hour=5)84 # Event.objects.filter(timestamp__hour__gte=12)85 86 # minute87 #88 # Event.objects.filter(timestamp__minute=29)89 # Event.objects.filter(time__minute=46)90 # Event.objects.filter(timestamp__minute__gte=29)91 92 # second93 #94 # Event.objects.filter(timestamp__second=31)95 # Event.objects.filter(time__second=2)96 # Event.objects.filter(timestamp__second__gte=31)
1 # extra #额外查询条件以及相关表,排序 2 # 3 # extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None) 4 # a. 映射 5 # select 6 # select_params=None 7 # select 此处 from 表 8 9 # b. 条件10 # where=None11 # params=None,12 # select * from 表 where 此处13 14 # c. 表15 # tables16 # select * from 表,此处17 18 # c. 排序19 # order_by=None20 # select * from 表 order by 此处21 22 # Entry.objects.extra(select={‘new_id‘: "select col from sometable where othercol > %s"}, select_params=(1,))23 # Entry.objects.extra(where=[‘headline=%s‘], params=[‘Lennon‘])24 # Entry.objects.extra(where=["foo=‘a‘ OR bar = ‘a‘", "baz = ‘a‘"])25 # Entry.objects.extra(select={‘new_id‘: "select id from tb where id > %s"}, select_params=(1,), order_by=[‘-nid‘])26 27 # F #更新时用于获取原来的值28 29 from django.db.models import F30 models.Tb1.objects.update(num=F(‘num‘)+1)31 32 33 # Q #用于构造复杂查询条件34 35 # 应用一:36 models.UserInfo.objects.filter(Q(id__gt=1))37 models.UserInfo.objects.filter(Q(id=8) | Q(id=2))38 models.UserInfo.objects.filter(Q(id=8) & Q(id=2))39 40 # 应用二:41 # con = Q()42 # q1 = Q()43 # q1.connector = ‘OR‘44 # q1.children.append((‘id‘, 1))45 # q1.children.append((‘id‘, 10))46 # q1.children.append((‘id‘, 9))47 # q2 = Q()48 # q2.connector = ‘OR‘49 # q2.children.append((‘c1‘, 1))50 # q2.children.append((‘c1‘, 10))51 # q2.children.append((‘c1‘, 9))52 # con.add(q1, ‘AND‘)53 # con.add(q2, ‘AND‘)54 #55 # models.Tb1.objects.filter(con)56 57 58 # 执行原生SQL59 #60 # from django.db import connection, connections61 # cursor = connection.cursor() # cursor = connections[‘default‘].cursor()62 # cursor.execute("""SELECT * from auth_user where id = %s""", [1])63 # row = cursor.fetchone()
1 ################################################################## 2 # PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET # 3 ################################################################## 4 5 def all(self) 6 # 获取所有的数据对象 7 8 def filter(self, *args, **kwargs) 9 # 条件查询 10 # 条件可以是:参数,字典,Q 11 12 def exclude(self, *args, **kwargs) 13 # 条件查询 14 # 条件可以是:参数,字典,Q 15 16 def select_related(self, *fields) 17 性能相关:表之间进行join连表操作,一次性获取关联的数据。 18 model.tb.objects.all().select_related() 19 model.tb.objects.all().select_related(‘外键字段‘) 20 model.tb.objects.all().select_related(‘外键字段__外键字段‘) 21 22 def prefetch_related(self, *lookups) 23 性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。 24 # 获取所有用户表 25 # 获取用户类型表where id in (用户表中的查到的所有用户ID) 26 models.UserInfo.objects.prefetch_related(‘外键字段‘) 27 28 29 30 from django.db.models import Count, Case, When, IntegerField 31 Article.objects.annotate( 32 numviews=Count(Case( 33 When(readership__what_time__lt=treshold, then=1), 34 output_field=CharField(), 35 )) 36 ) 37 38 students = Student.objects.all().annotate(num_excused_absences=models.Sum( 39 models.Case( 40 models.When(absence__type=‘Excused‘, then=1), 41 default=0, 42 output_field=models.IntegerField() 43 ))) 44 45 def annotate(self, *args, **kwargs) 46 # 用于实现聚合group by查询 47 48 from django.db.models import Count, Avg, Max, Min, Sum 49 50 v = models.UserInfo.objects.values(‘u_id‘).annotate(uid=Count(‘u_id‘)) 51 # SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id 52 53 v = models.UserInfo.objects.values(‘u_id‘).annotate(uid=Count(‘u_id‘)).filter(uid__gt=1) 54 # SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1 55 56 v = models.UserInfo.objects.values(‘u_id‘).annotate(uid=Count(‘u_id‘,distinct=True)).filter(uid__gt=1) 57 # SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1 58 59 def distinct(self, *field_names) 60 # 用于distinct去重 61 models.UserInfo.objects.values(‘nid‘).distinct() 62 # select distinct nid from userinfo 63 64 注:只有在PostgreSQL中才能使用distinct进行去重 65 66 def order_by(self, *field_names) 67 # 用于排序 68 models.UserInfo.objects.all().order_by(‘-id‘,‘age‘) 69 70 def extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None) 71 # 构造额外的查询条件或者映射,如:子查询 72 73 Entry.objects.extra(select={‘new_id‘: "select col from sometable where othercol > %s"}, select_params=(1,)) 74 Entry.objects.extra(where=[‘headline=%s‘], params=[‘Lennon‘]) 75 Entry.objects.extra(where=["foo=‘a‘ OR bar = ‘a‘", "baz = ‘a‘"]) 76 Entry.objects.extra(select={‘new_id‘: "select id from tb where id > %s"}, select_params=(1,), order_by=[‘-nid‘]) 77 78 def reverse(self): 79 # 倒序 80 models.UserInfo.objects.all().order_by(‘-nid‘).reverse() 81 # 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序 82 83 84 def defer(self, *fields): 85 models.UserInfo.objects.defer(‘username‘,‘id‘) 86 或 87 models.UserInfo.objects.filter(...).defer(‘username‘,‘id‘) 88 #映射中排除某列数据 89 90 def only(self, *fields): 91 #仅取某个表中的数据 92 models.UserInfo.objects.only(‘username‘,‘id‘) 93 或 94 models.UserInfo.objects.filter(...).only(‘username‘,‘id‘) 95 96 def using(self, alias): 97 指定使用的数据库,参数为别名(setting中的设置) 98 99 100 ##################################################101 # PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #102 ##################################################103 104 def raw(self, raw_query, params=None, translations=None, using=None):105 # 执行原生SQL106 models.UserInfo.objects.raw(‘select * from userinfo‘)107 108 # 如果SQL是其他表时,必须将名字设置为当前UserInfo对象的主键列名109 models.UserInfo.objects.raw(‘select id as nid from 其他表‘)110 111 # 为原生SQL设置参数112 models.UserInfo.objects.raw(‘select id as nid from userinfo where nid>%s‘, params=[12,])113 114 # 将获取的到列名转换为指定列名115 name_map = {‘first‘: ‘first_name‘, ‘last‘: ‘last_name‘, ‘bd‘: ‘birth_date‘, ‘pk‘: ‘id‘}116 Person.objects.raw(‘SELECT * FROM some_other_table‘, translations=name_map)117 118 # 指定数据库119 models.UserInfo.objects.raw(‘select * from userinfo‘, using="default")120 121 ################### 原生SQL ###################122 from django.db import connection, connections123 cursor = connection.cursor() # cursor = connections[‘default‘].cursor()124 cursor.execute("""SELECT * from auth_user where id = %s""", [1])125 row = cursor.fetchone() # fetchall()/fetchmany(..)126 127 128 def values(self, *fields):129 # 获取每行数据为字典格式130 131 def values_list(self, *fields, **kwargs):132 # 获取每行数据为元祖133 134 def dates(self, field_name, kind, order=‘ASC‘):135 # 根据时间进行某一部分进行去重查找并截取指定内容136 # kind只能是:"year"(年), "month"(年-月), "day"(年-月-日)137 # order只能是:"ASC" "DESC"138 # 并获取转换后的时间139 - year : 年-01-01140 - month: 年-月-01141 - day : 年-月-日142 143 models.DatePlus.objects.dates(‘ctime‘,‘day‘,‘DESC‘)144 145 def datetimes(self, field_name, kind, order=‘ASC‘, tzinfo=None):146 # 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间147 # kind只能是 "year", "month", "day", "hour", "minute", "second"148 # order只能是:"ASC" "DESC"149 # tzinfo时区对象150 models.DDD.objects.datetimes(‘ctime‘,‘hour‘,tzinfo=pytz.UTC)151 models.DDD.objects.datetimes(‘ctime‘,‘hour‘,tzinfo=pytz.timezone(‘Asia/Shanghai‘))152 153 """154 pip3 install pytz155 import pytz156 pytz.all_timezones157 pytz.timezone(‘Asia/Shanghai’)158 """159 160 def none(self):161 # 空QuerySet对象162 163 164 ####################################165 # METHODS THAT DO DATABASE QUERIES #166 ####################################167 168 def aggregate(self, *args, **kwargs):169 # 聚合函数,获取字典类型聚合结果170 from django.db.models import Count, Avg, Max, Min, Sum171 result = models.UserInfo.objects.aggregate(k=Count(‘u_id‘, distinct=True), n=Count(‘nid‘))172 ===> {‘k‘: 3, ‘n‘: 4}173 174 def count(self):175 # 获取个数176 177 def get(self, *args, **kwargs):178 # 获取单个对象179 180 def create(self, **kwargs):181 # 创建对象182 183 def bulk_create(self, objs, batch_size=None):184 # 批量插入185 # batch_size表示一次插入的个数186 objs = [187 models.DDD(name=‘r11‘),188 models.DDD(name=‘r22‘)189 ]190 models.DDD.objects.bulk_create(objs, 10)191 192 def get_or_create(self, defaults=None, **kwargs):193 # 如果存在,则获取,否则,创建194 # defaults 指定创建时,其他字段的值195 obj, created = models.UserInfo.objects.get_or_create(username=‘root1‘, defaults={‘email‘: ‘1111111‘,‘u_id‘: 2, ‘t_id‘: 2})196 197 def update_or_create(self, defaults=None, **kwargs):198 # 如果存在,则更新,否则,创建199 # defaults 指定创建时或更新时的其他字段200 obj, created = models.UserInfo.objects.update_or_create(username=‘root1‘, defaults={‘email‘: ‘1111111‘,‘u_id‘: 2, ‘t_id‘: 1})201 202 def first(self):203 # 获取第一个204 205 def last(self):206 # 获取最后一个207 208 def in_bulk(self, id_list=None):209 # 根据主键ID进行查找210 id_list = [11,21,31]211 models.DDD.objects.in_bulk(id_list)212 213 def delete(self):214 # 删除215 216 def update(self, **kwargs):217 # 更新218 219 def exists(self):220 # 是否有结果221 222 其他操作
十三、多表关系以及参数
1 ForeignKey(ForeignObject) # ForeignObject(RelatedField) 2 to, # 要进行关联的表名 3 to_field=None, # 要关联的表中的字段名称 4 on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为 5 - models.CASCADE,删除关联数据,与之关联也删除 6 - models.DO_NOTHING,删除关联数据,引发错误IntegrityError 7 - models.PROTECT,删除关联数据,引发错误ProtectedError 8 - models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空) 9 - models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值) 10 - models.SET,删除关联数据, 11 a. 与之关联的值设置为指定值,设置:models.SET(值) 12 b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象) 13 14 def func(): 15 return 10 16 17 class MyModel(models.Model): 18 user = models.ForeignKey( 19 to="User", 20 to_field="id" 21 on_delete=models.SET(func),) 22 related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all() 23 related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values(‘表名__字段名‘) 24 limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件: 25 # 如: 26 - limit_choices_to={‘nid__gt‘: 5} 27 - limit_choices_to=lambda : {‘nid__gt‘: 5} 28 29 from django.db.models import Q 30 - limit_choices_to=Q(nid__gt=10) 31 - limit_choices_to=Q(nid=8) | Q(nid__gt=10) 32 - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption=‘root‘) 33 db_constraint=True # 是否在数据库中创建外键约束 34 parent_link=False # 在Admin中是否显示关联数据 35 36 37 OneToOneField(ForeignKey) 38 to, # 要进行关联的表名 39 to_field=None # 要关联的表中的字段名称 40 on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为 41 42 ###### 对于一对一 ###### 43 # 1. 一对一其实就是 一对多 + 唯一索引 44 # 2.当两个类之间有继承关系时,默认会创建一个一对一字段 45 # 如下会在A表中额外增加一个c_ptr_id列且唯一: 46 class C(models.Model): 47 nid = models.AutoField(primary_key=True) 48 part = models.CharField(max_length=12) 49 50 class A(C): 51 id = models.AutoField(primary_key=True) 52 code = models.CharField(max_length=1) 53 54 ManyToManyField(RelatedField) 55 to, # 要进行关联的表名 56 related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all() 57 related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values(‘表名__字段名‘) 58 limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件: 59 # 如: 60 - limit_choices_to={‘nid__gt‘: 5} 61 - limit_choices_to=lambda : {‘nid__gt‘: 5} 62 63 from django.db.models import Q 64 - limit_choices_to=Q(nid__gt=10) 65 - limit_choices_to=Q(nid=8) | Q(nid__gt=10) 66 - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption=‘root‘) 67 symmetrical=None, # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段 68 # 做如下操作时,不同的symmetrical会有不同的可选字段 69 models.BB.objects.filter(...) 70 71 # 可选字段有:code, id, m1 72 class BB(models.Model): 73 74 code = models.CharField(max_length=12) 75 m1 = models.ManyToManyField(‘self‘,symmetrical=True) 76 77 # 可选字段有: bb, code, id, m1 78 class BB(models.Model): 79 80 code = models.CharField(max_length=12) 81 m1 = models.ManyToManyField(‘self‘,symmetrical=False) 82 83 through=None, # 自定义第三张表时,使用字段用于指定关系表 84 through_fields=None, # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表 85 from django.db import models 86 87 class Person(models.Model): 88 name = models.CharField(max_length=50) 89 90 class Group(models.Model): 91 name = models.CharField(max_length=128) 92 members = models.ManyToManyField( 93 Person, 94 through=‘Membership‘, 95 through_fields=(‘group‘, ‘person‘), 96 ) 97 98 class Membership(models.Model): 99 group = models.ForeignKey(Group, on_delete=models.CASCADE)100 person = models.ForeignKey(Person, on_delete=models.CASCADE)101 inviter = models.ForeignKey(102 Person,103 on_delete=models.CASCADE,104 related_name="membership_invites",105 )106 invite_reason = models.CharField(max_length=64)107 db_constraint=True, # 是否在数据库中创建外键约束108 db_table=None, # 默认创建第三张表时,数据库中表的名称
框架----Django框架知识点整理
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。