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结果集整合。

···
原文地址:https://www.cnblogs.com/G-YUE/p/7106135.html