django

django

一、安裝

pip install django

二、基本配置

建立django程序

終端命令:django-admin startproject 項目名

IDE建立django項目時,本質上都是執行上述命令

  python manage.py runserver 0.0.0.0css

  python manage.py startapp appname #新建apphtml

  python manage.py makemigrations #遷移數據python

  python manage.py migrate #同步到數據庫mysql

  python manage.py createsuperuser #建立超級用戶jquery

程序目錄

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'),
    )

靜態文件

三、靜態文件web

在文件最後加入
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'),

設置名稱以後,能夠在不一樣的地方調用,如:ajax

模板中使用生成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。這個參數包含着從瀏覽器發過來的全部數據。sql

一、method數據庫

request.method:顯示的是請求方式是GET仍是POST。

二、傳入的值django

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網站)

好處:敏感信息不會直接給客戶端

存放位置

一、數據庫中   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,默認修改以後才保存(默認)
        


二、緩存中

    a. 配置 settings.py
        SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
        SESSION_CACHE_ALIAS = 'default'                            # 使用的緩存別名(默認內存緩存,也能夠是memcache),此處別名依賴緩存的設置
        
    其餘同上

三、文件中

    a. 配置 settings.py
        SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
        SESSION_FILE_PATH = None                                    # 緩存文件路徑,若是爲None,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir() 
    其餘同上

四、加密的cookie中
    a. 配置 settings.py
        SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎

五、緩存+數據庫

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

···
相關文章
相關標籤/搜索