zoukankan      html  css  js  c++  java
  • django

    django

    1、安装

    pip install django
    

    2、基本配置

    创建django程序

    终端命令:django-admin startproject 项目名
    
    IDE创建django项目时,本质上都是执行上述命令
    

      python manage.py runserver 0.0.0.0

      python manage.py startapp appname #新建app

      python manage.py makemigrations #迁移数据

      python manage.py migrate #同步到数据库

      python manage.py createsuperuser #创建超级用户

    程序目录

    django-admin startproject mysite
    
    python manage.py startapp appname  #新建app
    

    -mysite
    	-mysite
    		settings.py  配置文件
    		urls.py	     路由系统
    		wsgi.py      web服务网关
    
    	-app01
    		admin.py  django自带后台管理
    		models.py 写类,根据类创建数据库数据
    		tests.py  单元测试
    		view.py   业务处理
    
    	-templates  存放页面,图片等
    		index.html
    
    	-static    存放静态文件CSS、JS等  需要在settings中设置
    		-css
    		-js
    	manage.py  管理和启动文件
    	db.sqlte3    数据库
    

    配置文件 setting.py

    数据库

    DATABASES = {
        'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'dbname',
        'USER': 'root',
        'PASSWORD': 'xxx',
        'HOST': '',
        'PORT': '',
        }
    }
    
    
    # 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替
      
    # 如下设置放置的与project同名的配置的 __init__.py文件中
      
    import pymysql
    pymysql.install_as_MySQLdb() 
    

    模版路径

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

    静态文件

    3、静态文件

        在文件最后加入
    STATICFILES_DIRS = (
            os.path.join(BASE_DIR,'指定文件夹'),
        )
    

    路由系统

    单一路由对应

    url(r'^index$', views.index),
    ps:
    	127.0.0.1:8000/index
    

    基于正则的路由

    url(r'^index/(d*)', views.index),
    
    ps:
    	127.0.0.1:8000/index/0-无穷个数字
    	index要有足够的位置参数 index(request,id)
    
    url(r'^manage/(?P<name>w*)/(?P<id>d*)', views.manage),
    
    ps:
    	127.0.0.1:8000/manage/adsa/123
    
    manage中需要对应参数接收 manage(request,name,id)
    

    添加额外的参数

    url(r'^manage/(?P<name>w*)', views.manage,{'id':333}),
    
    ps:
    	manage(request,name,id)
    

    为路由设置别称

    url(r'^home', views.home, name='h1'),
    url(r'^index/(d*)', views.index, name='h2'),
    

    设置名称之后,可以在不同的地方调用,如:

    模板中使用生成URL     {% url 'h2' 2012 %}
    函数中使用生成URL     reverse('h2', args=(2012,))      路径:django.urls.reverse
    Model中使用获取URL  自定义get_absolute_url() 方法
    

    根据app对路由规则进行分类

        from django.conf.urls import url,include
    
    url(r'^web/',include('web.urls')),      
    
        在web的urls.py 中再设置web后面的URL参数
    

    模版

    模版的执行


    from django.shortcuts import HttpResponse
    
    def current_datetime(request):
        now = datetime.datetime.now()
        html = "<html><body>It is now %s.</body></html>" % now
        return HttpResponse(html)
    #HttpResponse()  返回的是字符串
    

    from django import template
    
    t = template.Template('My name is {{ name }}.')  #template后面跟的是模版的字符串
    
    c = template.Context({'name': 'Adrian'})   #context用来实现替换模版中的占位符
    print t.render(c)   
    
    #render()返回的是完整的模版字符串
    

    import datetime
    from django import template
    import DjangoDemo.settings
     
    now = datetime.datetime.now()
    fp = open(settings.BASE_DIR+'/templates/Home/Index.html')  #打开模版HTML,获得文件句柄
    t = template.Template(fp.read())  #读取模版内容
    fp.close()
    html = t.render(template.Context({'current_date': now}))  #替换占位符
    return HttpResponse(html)
    

    from django.template.loader import get_template
    from django.template import Context
    from django.http import HttpResponse
    import datetime
     
    def current_datetime(request):
        now = datetime.datetime.now()
        t = get_template('current_datetime.html')
        html = t.render(Context({'current_date': now}))
        return HttpResponse(html)
    

    return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))
    

    模版语言

    {{ item }}
    
    {% for item in item_list %}  
    
    	<a>{{ item.0 }}</a> 
    
    	<a>{{ item.id }}</a> 
    
    {% endfor %}
    
    {% if ordered_warranty %}  
    
    {% else %} 
    
    {% endif %}
    
    母板:{% block title %}{% endblock %}
    
    子板:{% extends "base.html" %}
       {% block title %}{% endblock %}
    
        组件:include
    
         {% include "组件.html" %}
    
    
        pub.html
    	    <div>
    		    <h3>特别漂亮的组件</h3>
    		    <div class="title">标题:{{ name }}</div>
    		    <div class="content">内容:{{ name }}</div>
    	    </div>
        test.html
    	<!DOCTYPE html>
    	<html lang="en">
    	<head>
    		<meta charset="UTF-8">
    		<title></title>
    	</head>
    	<body>
    		{% include 'pub.html' %}
    		{% include 'pub.html' %}
    		{% include 'pub.html' %}
    	</body>
    	</html>
    
    
    帮助方法:
    {{ item.event_start|date:"Y-m-d H:i:s"}}
    {{ bio|truncatewords:"30" }}
    {{ my_list|first|upper }}
    {{ name|lower }}
    
    PS:
    	ajax先服务器提交信息并等待接受
    
    $.ajax({
        url: "/submit/",  #向哪个url提交数据
        type: "POST",    #以某种方式发送POST或者GET
        data: da,       #数据,如果数据中有列表或其他非字符串类型,jquery会对键值做一些处理,可以在后面添加一个属性,traditional:true
    
    		{"list":[1,2,3]} 发送到后台就会变成{"list[]":[1,2,3]}
    
    		{"list":[1,2,3]},traditional:true   发送到后台:{"list":[1,2,3]}
    
        success: function (data) {  #data是从服务器返回的数据
            if (data == "false") {
                $("#msg").text("不能为空!!!");
            }
            else {
                location.href = data;
            }
        }
    
    })
    服务端发送回来的只能是字符串,render返回的也是字符串,不会实现跳转。这里值得一提的是可以用json来传送字典。
    服务器端:
    	import json
    	dict={"title":1,"id":2}
    	return HttpResponse(json.dumps(dict))
    
    浏览器ajax success接收:
    	Json.parse(data)   将json字符串data转化成dict
    
    	Json.stringify(dict) 将dict转化成字符串
    

    request属性

    我们定义一个个函数,都至少有一个request。这个参数包含着从浏览器发过来的所有数据。

    1、method

    request.method:显示的是请求方式是GET还是POST。 
    

    2、传入的值

    request.GET  :显示的是由GET方式传入的参数。也就是通过url的方式或者ajax指定。
    
    request.POST : 显示的是由POST方式传入的参数,有表单form还有ajax等方式。
    
    request.GET.get("键值") 可以获取指定的参数。如果值是列表,那么就用getlist
    

    今日小知识

    form的submit和a标签如果有href的话,都有默认跳转,如果我们给他们加了一个click事件,那么等click事件完成,他们还是会执行默认的跳转事件,如何阻止呢,我们可以在click函数中加一句 return false 这样就可以阻止了。

    如何获取select下的所有的option标签value:

    $("#Newclist option").map(function(){return $(this).val();}).get().join(",");
    
    #Newclist是select标签的ID 。
    
    $().map(function()
    {
    	return $(this).val();
    }).get()  这样获取到的是一个列表,可以通过join的方式拼接成一个字符串。
    

    在js中如何判断一个值在不在一个数组里:

    可以用indexof:[11,22,33].indexof(22)  存在会返回索引值  不存在会返回-1			
    

    XSS攻击

    	- 慎用 safe和mark_safe
    	-from django.utils.safestring import mark_safe
    	- 非要用,一定要过滤关键字
    
    
    
    	评论等。客户输入的评论不是正常评论。比如<scrip>  alert(123) </scrip>
    	如果直接显示到网页中,则是以代码显示的,每次打开这个页面都会执行一个弹出框。
    
    	django自带的对这些进行了处理。如果是非正常字符串,则在网页中他们是以字符串形式显示的。
    
    	如果要让他们以原有的形式显示,{{ aaa | safe }}   加上safe  
    
    	或者传入的时候用mark_safe修改下。
    
        from django.utils.safestring import mark_safe
        x="<a href='http://www.baidu.com'>sss</a>"
        return render(request,"test.html",{"a":mark_safe(x)})
    

    django自带分页

    from django.core.paginator import Paginator,Page
    
    
    def index(request):
    
    
    	current_page = request.GET.get('page') #获取页码
    
        user_list = models.UserInfo.objects.all()  #从数据库中查询数据
        paginator = Paginator(user_list,10)      #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})
    
    
    	html:
    		{% for i in posts.object_list %}
    			{{ i }}
    		{% endfor %}
    

    自定义分页

    def newpage(request):
    	page=request.GET.get("page")
    
    	1   0 -10
    	2   10-20
    
    
    	start_page=(page-1)*10
    	end_page=page*10
    
    	user_list=models.Userinfo.objects.all()[start_page,end_page]
    	
    	return render(request,"user.html",{"userlist":user_list})
    

    CSRF

    1. CSRF
    	a. 基本应用
    		form表单中添加
    		{% csrf_token %}
    	
    	b. 全站禁用
    		# 'django.middleware.csrf.CsrfViewMiddleware',
    	
    	c. 局部禁用
    		'django.middleware.csrf.CsrfViewMiddleware',
    		
    		from django.views.decorators.csrf import csrf_exempt
    
    		@csrf_exempt
    		def csrf1(request):
    
    			if request.method == 'GET':
    				return render(request,'csrf1.html')
    			else:
    				return HttpResponse('ok')
    	d. 局部使用
    		# 'django.middleware.csrf.CsrfViewMiddleware',
    		
    		from django.views.decorators.csrf import csrf_exempt,csrf_protect
    
    		@csrf_protect
    		def csrf1(request):
    
    			if request.method == 'GET':
    				return render(request,'csrf1.html')
    			else:
    				return HttpResponse('ok')
    	
    	c. 特殊CBV
    			from django.views import View
    			from django.utils.decorators import method_decorator
    			
    			@method_decorator(csrf_protect,name='dispatch')
    			class Foo(View):
    				
    				def get(self,request):
    					pass
    
    				def post(self,request):
    					pass
    	
    	PS:CBV中添加装饰器
    		def wrapper(func):
    			def inner(*args,**kwargs):
    				return func(*args,**kwargs)
    			return inner
    		# 1. 指定方法上添加装饰器
    
    			# class Foo(View):
    			#
    			#     @method_decorator(wrapper)
    			#     def get(self,request):
    			#         pass
    			#
    			#     def post(self,request):
    			#         pass
    		# 2. 在类上添加
    			#     @method_decorator(wrapper,name='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. 放在请求头中  cookie和csrf_token 的值是不一样的
    		
    				<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>
    

    COOKIE和SESSION

    a、保存在浏览器端的"键值对",服务端可以向浏览器端写cookie
    b、浏览器每次发送请求时,会携带cookie	
    
    应用:
    	a、投票
    	b、用户登录
    
    登录时,如果用户名和密码正确,可以写
    	obj=render(request,"index.html")
    	obj.set_cookie("键","值",max_age=10,path="/")  #max_age超时时间,浏览器保存的cookie有效时间。 10秒
    
    										            	#或者expires 他跟的参数是2017年6月21日 11:50:58
    										            	#path 指定某个url可以使用当前的cookie path="/index/"    /表示所有url都可以用
    
    	return obj
    
    
    	obj=set_signed_cookie("键","值",salt="加盐操作")
    
    接收端接收cookie
    	cook=request.COOKIES.get("上面中的键")
    	cook=request.get_signed_cookie("键",salt="加盐")
    

    SESSION

    a、保存在服务器端的数据(本质是键值对)
    
    b、依赖cookie
    
    c、保持会话(web网站)
    
    好处:敏感信息不会直接给客户端
    

    存放位置

    1、数据库中   django默认存放在数据库中
    
    	Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。
    
    	a. 配置 settings.py
    
    	    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
    	     
    	    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    	    SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
    	    SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
    	    SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
    	    SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
    	    SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
    	    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
    	    SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
    	    
    
    
    2、缓存中
    
    	a. 配置 settings.py
    		SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
    		SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
    		
    	其他同上
    
    3、文件中
    
    	a. 配置 settings.py
    		SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
    		SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 
    	其他同上
    
    4、加密的cookie中
    	a. 配置 settings.py
    		SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
    
    5、缓存+数据库
    
    	a. 配置 settings.py
    		SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
    

    查询、设置、删除、修改

    # 获取、设置、删除Session中数据
        request.session['k1']     #不存在会报错
        request.session.get('k1',None)
        request.session['k1'] = 123
        request.session.setdefault('k1',123) # 存在则不设置
    
    
        del request.session['k1']
    	request.session.delete(request.session.session_key)  #删除session
    	request.session.clear()   #删除cookie
    	
    # 所有 键、值、键值对
        request.session.keys()
        request.session.values()
        request.session.items()
        request.session.iterkeys()
        request.session.itervalues()
        request.session.iteritems()
    
    
    # 用户session的随机字符串
    	request.session.session_key
    
    # 将所有Session失效日期小于当前日期的数据删除
    	request.session.clear_expired()
    
    # 检查 用户session的随机字符串 在数据库中是否
    	request.session.exists("session_key")
    
    # 删除当前用户的所有Session数据
    	request.session.delete("session_key")
    
    # 设置失效期
        request.session.set_expiry(value)
            * 如果value是个整数,session会在些秒数后失效。
            * 如果value是个datatime或timedelta,session就会在这个时间后失效。
            * 如果value是0,用户关闭浏览器session就会失效。
            * 如果value是None,session会依赖全局session失效策略。
    

    CBV 和 FBV

    CBV url--->类

    url(r'^index.html$', views.Login.as_view()),
    
    app01.views
    
    from django.views import View
    class Login(View):
    	'''
    		get     查
    		post    创建
    		put	    更新
    		delete  删除
    	'''
    	def dispath(self,request,*args,**kwargs):
    		obj= super(Login,self).dispatj(request,*args,**kwargs)   继承父类方法
    		return obj
    
    	def get(self,request):  如果是以get方式访问的执行这个函数
    		return HttpResponse("get")
    
    	def post(self,request):如果是以post方式访问的执行这个函数
    		return HttpResponse("post")
    

    FBV

    	url(r'^index.html$', views.index),
    
        app01.views
    
        def indes(request):
            return Httpresponse("index")    
    

    正向操作:

    all():返回的是对象

    a=models.Userinfo.objects.all()    #返回的是一个queryset类型的列表,里面是一个个userinfo.object对象
    b=models.Userinfo.objects.all().first()  #返回的是all查询结果的第一条userinfo.object对象
    
    for i in a:
        print(i.id,i.user)
    
    print(b.id,b.user)
    

    values:返回的是字典

    a=models.Userinfo.objects.values("id","user","pawd")
    
    <QuerySet [{'id': 1, 'user': 'egon', 'pawd': '123'}, 
    			{'id': 2, 'user': 'alex', 'pawd': '123'}, 
    			{'id': 3, 'user': 'alvin', 'pawd': '123'},
    			 {'id': 4, 'user': 'wusir', 'pawd': '123'},
    			 {'id': 5, 'user': 'gao', 'pawd': '123123'},
    			 {'id': 6, 'user': 'sunqi', 'pawd': '123'}]>
    
    
    b=models.Userinfo_group.objects.values("id","uid__user","gid__gname")
    
    
    <QuerySet [{'id': 1, 'uid__user': 'egon', 'gid__gname': '主机1'}, 
    			{'id': 2, 'uid__user': 'alex', 'gid__gname': '主机1'}, 
    			{'id': 3, 'uid__user': 'alvin', 'gid__gname': '主机1'},
    			 {'id': 4, 'uid__user': 'alex', 'gid__gname': '主机2'}, 
    			{'id': 5, 'uid__user': 'alvin', 'gid__gname': '主机2'}, 
    			{'id': 6, 'uid__user': 'wusir', 'gid__gname': '主机2'}, 
    			{'id': 7, 'uid__user': 'egon', 'gid__gname': '主机3'}, 
    			{'id': 8, 'uid__user': 'alex', 'gid__gname': '主机3'}, 
    			{'id': 9, 'uid__user': 'alvin', 'gid__gname': '主机4'},
    			 {'id': 10, 'uid__user': 'wusir', 'gid__gname': '主机4'}]>
    
    
    
    for i in a:
        print(i["id"],i["user"],i["pawd"])
    for i in b:
        print(i["id"],i["uid__user"],i["gid__gname"])
    

    values_list: 返回的是元祖

    a=models.Userinfo.objects.values_list("id","user","pawd")
    
    	(1, 'egon', '123')
    	(2, 'alex', '123')
    	(3, 'alvin', '123')
    	(4, 'wusir', '123')
    	(5, 'gao', '123123')
    	(6, 'sunqi', '123')
    
    
    
    b=models.Userinfo_group.objects.values_list("id","uid__user","gid__gname")
    
    	(1, 'egon', '主机1')
    	(2, 'alex', '主机1')
    	(3, 'alvin', '主机1')
    	(4, 'alex', '主机2')
    	(5, 'alvin', '主机2')
    	(6, 'wusir', '主机2')
    	(7, 'egon', '主机3')
    	(8, 'alex', '主机3')
    	(9, 'alvin', '主机4')
    	(10, 'wusir', '主机4')
    
    for i in a:
        print(i[0],i[1],i[2])
    
    
    for i in b:
        print(i[0],i[1],i[2])
    

    反向操作 userinfo中引用了usergroup的ID外键

    小写的表名_set

    	obj = models.UserGroup.objects.all().first()
       result = obj.userinfo_set.all() [userinfo对象,userinfo对象,]
    

    小写的表名 values

    	v = models.UserGroup.objects.values('id','title')          
    	v = models.UserGroup.objects.values('id','title','小写的表名称')          
    	v = models.UserGroup.objects.values('id','title','小写的表名称__age')          
    

    小写的表名 values_list
    v = models.UserGroup.objects.values_list('id','title')
    v = models.UserGroup.objects.values_list('id','title','小写的表名称')
    v = models.UserGroup.objects.values_list('id','title','小写的表名称__age')

    PS: 前面的所有数据都会显示
    

    跨表:Userinfo和Usergroup是两张独立的表,userinfo_group是有两个列分别调用的userinfo和usergroup两个表的id

    	正向:
    
    		a=models.Userinfo_group.objects.filter(uid__user="egon").values("id","uid__user","gid__gname")
    
    		{'id': 1, 'uid__user': 'egon', 'gid__gname': '主机1'}
    		{'id': 7, 'uid__user': 'egon', 'gid__gname': '主机3'}
    
    
    	    for i in a:
    	        print(i["id"], i["uid__user"], i["gid__gname"])
    	
    
    	反向:
    
    		a=models.Userinfo.objects.filter(userinfo_group=1).values("id","user","userinfo_group__gid__gname")
    
    		{'id': 1, 'user': 'egon', 'userinfo_group__gid__gname': '主机1'}
    
    		for i in a:
        		print(i["id"],i["user"],i["userinfo_group__gid__gname"])
    
    • 其他:
      models.UserInfo.objects.all()

        models.UserInfo.objects.filter(age__isnull=True)  #查找age列值为空的数据
      
        models.UserInfo.objects.all().only("id")   #只取ID列
      
        models.UserInfo.objects.all().defer("id")  #不取ID列
      
      
        models.UserGroup.objects.values('id','title').distinct()  #表示按照id和title去重 
      
      
      
        models.UserInfo.objects.filter(id=1,id=2)  # id=1 and id=2
      
        models.UserInfo.objects.filter(id=1,id=2).exsit()  #是否存在,True False
      
      
        models.UserInfo.objects.all().first()  #第一条数据
      
        models.UserInfo.objects.all().last()  #最后一条数据
      
      
        models.UserInfo.objects.all().count()  #数据总共有多少行
      
        models.UserInfo.objects.all().update() #更新
      
        models.UserInfo.objects.all().delete()  #删除
      
        #无论是增删改查,参数都可以加字典操作。
      
        	models.xx.objects.filter(id=1,name="alex")
        	models.xx.objects.filter(**{'id':1,'name':'alex'})
      
      
        models.UserInfo.objects.all()[1:19]   #切片
      
      
      
        # models.UserInfo.objects.filter(id__gt=1) #id>1
      
        # models.UserInfo.objects.filter(id__lt=1) #id<1
      
        # models.UserInfo.objects.filter(id__lte=1) #id<=1
      
        # models.UserInfo.objects.filter(id__gte=1) #id>=1
      
      
        # models.UserInfo.objects.filter(id__in=[1,2,3]) #id in [1,2,3]
      
        # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
      
      
        # models.UserInfo.objects.filter(id__range=[1,2]) # between 1 and 2
      
        # models.UserInfo.objects.filter(name__startswith='xxxx')    #以xxxx开头
      
        # models.UserInfo.objects.filter(name__contains='xxxx')   #模糊匹配包含xxxx的name
      
        # models.UserInfo.objects.exclude(id=1)   #id != 1
      

    分组、排序、其他

    分组

    	from django.db.models import Count,Max,Min,Sum,Avg
    
    	obj=models.Userinfo.objects.values("ut_id").annotate(别名=Count("id"))
    
    	“select userinfo.ut_id,Count("id") as 别名  from userinfo group by userinfo.id”
    
    	obj.query   #显示对应的sql原生语句
    
    
    
    	#以主机ID分组,计算每组中有多少个用户
    	a=models.Userinfo_group.objects.values("gid").annotate(zhu=Count("id"))
    	
    	SELECT `userinfo_group`.`gid_id`, COUNT(`userinfo_group`.`id`) AS `zhu` FROM `userinfo_group` GROUP BY `userinfo_group`.`gid_id` ORDER BY NULL
    
    	<QuerySet [{'gid': 1, 'zhu': 3}, {'gid': 2, 'zhu': 3}, {'gid': 3, 'zhu': 2}, {'gid': 4, 'zhu': 2}]>
    	
    
    	#聚合
    	models.UserInfo.objects.all().aggregate(Count("age"))
    

    排序

    	models.Userinfo.objects.all().order_by("id") #按照ID从小到大排列
    
    	models.Userinfo.objects.all().order_by("-id") #按照ID从大到小排列
    
    	
    	#reverse 反转
    	models.Userinfo.objects.all().order_by("-id").reverse() #按照ID从小到大排列		
    

    其他 from django.db.models import F,Q

    F 更新时用于获取原来的值

    a=models.UserInfo.objects.all().update(age=F("age")+1)  #给所有的age都加1
    
    a的值是受影响的行数
    

    Q 用于构造复杂查询条件

    # 应用一:
    		# models.UserInfo.objects.filter(Q(id__gt=1))    #id>1
    		# models.UserInfo.objects.filter(Q(id=8) | Q(id=2))  #id=8 or id=2
    		# models.UserInfo.objects.filter(Q(id=8) & Q(id=2))   #id=8 and id=2   ---->id=8,id=2
    
    
    
    # 应用二:
    		# q1 = Q()    
    		# q1.connector = 'OR'
    		# q1.children.append(('id__gt', 1))
    		# q1.children.append(('id', 10))
    		# q1.children.append(('id', 9))
    		
    		id>1 or id=10 or id=9
    
    
    		# q2 = Q()
    		# q2.connector = 'OR'
    		# q2.children.append(('c1', 1))
    		# q2.children.append(('c1', 10))
    		# q2.children.append(('c1', 9))
    		
    
    		c1=1 or c1=10 or c1=9
    
    
    
    		# q3 = Q()
    		# q3.connector = 'AND'
    		# q3.children.append(('id', 1))
    		# q3.children.append(('id', 2))
    
    		# q2.add(q3,'OR')
    		
    
    		q3(id=1 and id=2) or q2(c1=1 or c1=10 or c1=9)
    
    
    		# con = Q()
    		# con.add(q1, 'AND')
    		# con.add(q2, 'AND')
    
    		q1 and q2
    		
    		# models.UserInfo.objects.filter(con)
    

    extra 额外查询条件以及相关表,排序

    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={'newid':'select count(1) from app01_usertype where id>%s'},   
    	select_params=[1,],
    
    	#(select count(1) from app01_usertype where id>1) as newid
    
    	# select 此处 from 表
    
    # b. 条件
    	# where=None
    	# params=None,
    
    	where = ['age>%s'],
    	params=[18,],
    
    	#where age>18
    
    	# select * from 表 where 此处
    
    # c. 表
    	# tables
    
    	tables=['app01_usertype']
    
    	select * from 表,app01_usertype
    
    	# select * from 表,此处
    	
    # c. 排序
    	# order_by=None
    
    	order_by=['-age'],   #-desc ,正常asc
    
    	# order by age desc
    
    	# 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()    #指定数据库  db2
    
    cursor.execute("""SELECT * from auth_user where id = %s""", [1])
    
    row = cursor.fetchone()
    row = cursor.fetchall()
    
    
    - extra
    - 原生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
    

    性能

    select_related:主动连表

    models.UserInfo.objects.all().select_related("ut")  在查询userinfo时直接将外键ut关联的表进行inner join连接,这样在for循环的时候就不会再次查询ut那个表
    
    models.UserInfo.objects.all().select_related("ut","gt") inner join 2个表
    
    models.UserInfo.objects.all().prefetch_related("ut")
    
    ···
    	select * from userinfo
    	Django内部:将外键的ID 全部拿到 去重 比如说是[1,2]
    	select * from usertype where id in [1,2]
    
    	django会把2个select结果集整合。
    
    ···
  • 相关阅读:
    JAVA编写的一个简单的Socket实现的HTTP响应服务器
    IPTV 质量评价方法已经不适用于 OTT TV 质量评价
    AAC规格(LC,HE,HEv2)及性能对比
    洛谷 P1572 计算分数
    洛谷 P2128 赤壁之战
    洛谷 P2818 天使的起誓
    洛谷 P3914 染色计数
    洛谷 P1193 洛谷团队训练VS传统团队训练
    洛谷 P1318 积水面积
    洛谷 P1061 Jam的计数法
  • 原文地址:https://www.cnblogs.com/G-YUE/p/7106135.html
Copyright © 2011-2022 走看看