Django - 05-Django高級(jí)

[toc]

1 靜態(tài)文件

定義:
        css、js另伍、圖片查乒、json文件陷虎、字體文件等

存儲(chǔ)位置:
        project/static/項(xiàng)目名/{css,js,img,json,font,other}
        
配置settings.py
        STATIC_URL = '/static/'
        STATICFILES_DIRS = [
            os.path.join(BASE_DIR, 'static'),
        ]
        
栗子:
        目錄結(jié)構(gòu):
            Project
             └─static
                └─myApp
                   ├─css
                   ├─font
                   ├─img
                   ├─js
                   ├─json
                   └─other
        index.html
                <head>
                    <meta charset="UTF-8">
                    <title>index</title>
                    <link rel="stylesheet" type="text/css" href="/static/myApp/css/style.css">
                </head>
                    <script type="text/javascript" src="/static/myApp/js/lance.js"></script>
                <body>
                    <h1>lance is a good man</h1>
                    <img src="/static/myApp/img/a.png" alt="">
                </body>
                
        style.css
                h1{color: red;}
        
        lance.js
                console.log('good man')
                

普通文件動(dòng)態(tài)加載static目錄:(有錯(cuò)誤 先別用)
        index.html
                {% load static from staticfiles %}
                <!DOCTYPE html>
                ...
                <img src="{% static 'myApp/img/a.png' %}" alt="">
                
        注意:
                這時(shí)的文件的鏈接路徑 已經(jīng)不需要從static開(kāi)始去寫(xiě)了器予;
                settings.py中的 STATICFILES_DIRS 配置項(xiàng)已經(jīng)無(wú)效偿枕;
                
                

2 中間件

2.1 概述

一個(gè)輕量級(jí)隙券、底層的插件榜聂,可以介入Django的請(qǐng)求響應(yīng);

2.2 方法

__init__
        不需要傳參數(shù)陌凳,服務(wù)器響應(yīng)第一個(gè)請(qǐng)求的時(shí)候調(diào)用剥懒;用于確定是否啟用該中間件;

process_request(self, request)
        在分配url匹配視圖之前合敦,每個(gè)請(qǐng)求上都會(huì)調(diào)用初橘;返回 None 或者 HttpResponse 對(duì)象;

process_view(self, request, view_func, views_args, view_kwargs)
        調(diào)用視圖之前執(zhí)行,每個(gè)請(qǐng)求都會(huì)調(diào)用保檐;返回 None 或者 HttpResponse 對(duì)象耕蝉;

process_template(self, request, response)
        在視圖執(zhí)行完成后調(diào)用,每個(gè)請(qǐng)求都會(huì)調(diào)用夜只;返回 None 或者 HttpResponse 對(duì)象垒在;
        使用 render()
        
process_response(self, request, response)
        在執(zhí)行模板之后調(diào)用,每個(gè)請(qǐng)求都會(huì)調(diào)用扔亥;返回 HttpResponse 對(duì)象场躯;

process_exception(self, request, exception)
        當(dāng)視圖拋出異常時(shí)調(diào)用;返回 HttpResponse 對(duì)象旅挤;

2.3 自定義中間件

目錄結(jié)構(gòu):
        project/middleware/myApp/
        
創(chuàng)建中間件:
        myMiddler.py
                from django.utils.deprecation import MiddlewareMixin
                class MyMiddler(MiddlewareMixin):
                    def process_request(self, request):
                        print("GET參數(shù)為:", request.GET.get("a"))

使用中間件:
        配置settings.py踢关,在 MIDDLEWARE 中添加:
                'middleware.myApp.myMiddleware.MyMiddle',

驗(yàn)證:
        刷新界面,可以看到后臺(tái)粘茄,有打印信息签舞;

3 上傳圖片

3.1 概述

文件上傳時(shí),文件數(shù)據(jù)存儲(chǔ)在request.FILES屬性中柒瓣;

注意:
        form表單要上傳文件需要加 enctype="multipart/form-data" 儒搭;
        上傳文件必須是POST請(qǐng)求;

3.2 存儲(chǔ)配置

存儲(chǔ)路徑
        project/static/upfile

配置 settings.py:
        MEDIA_ROOT = os.path.join(BASE_DIR, 'static/upfile')

3.3 示例

upfile.html
        <form action="/savefile/" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <input type="file" name="file">
            <input type="submit" value="上傳">
        </form>
        
views.py
        def upfile(request):
            return render(request, 'myApp/upfile.html')
        
        import os
        from django.conf import settings
        def savefile(request):
            if request.method == "POST":
                f = request.FILES["file"]
                # 文件在服務(wù)器端的路徑
                filePath = os.path.join(settings.MEDIA_ROOT, f.name)
                with open(filePath, 'wb') as fp:
                    for info in f.chunks():     # 分段讀取文件內(nèi)容
                        fp.write(info)
                        fp.flush()
                return HttpResponse('上傳成功')
            else:
                return HttpResponse("上傳失敗")
                
urls.py
        url(r'^upfile/$', views.upfile),
        url(r'^savefile/$', views.savefile),

4 分頁(yè)

from django.core.paginator import Paginator

4.1 Paginator對(duì)象

創(chuàng)建對(duì)象
        格式:
                Paginator(列表, 整數(shù))       # (所有的數(shù)據(jù),每頁(yè)幾個(gè))
        
        返回值:
                返回分頁(yè)對(duì)象

屬性
        count       對(duì)象總數(shù)
        
        num_pages   頁(yè)面總數(shù)
        
        page_range  
                頁(yè)碼列表
                [1,2,3,4,5]
                頁(yè)碼從1開(kāi)始

方法
        page(num)
                獲得一個(gè)Page對(duì)象嘹朗,如果提供的頁(yè)碼不存在师妙,會(huì)拋出一個(gè) 'InvalidPage' 異常

異常
        InvalidPage
                當(dāng)向 page() 傳遞一個(gè)無(wú)效的頁(yè)碼時(shí)拋出;
                
        PageNotAnInteger
                當(dāng)向 page() 傳遞一個(gè)不是整數(shù)的參數(shù)時(shí)拋出屹培;

        EmptyPage
                當(dāng)向 page() 傳遞一個(gè)有效,但是該頁(yè)面沒(méi)有數(shù)據(jù)時(shí)拋出怔檩;

4.2 Page對(duì)象

創(chuàng)建對(duì)象
        Paginator對(duì)象的page方法返回得到Pafe對(duì)象褪秀;
        不需要手動(dòng)創(chuàng)建;

屬性
        object_list
                當(dāng)前頁(yè)上的所有的數(shù)據(jù)(對(duì)象)列表薛训;
                
        number
                當(dāng)前頁(yè)的頁(yè)碼值媒吗;
        
        paginator
                當(dāng)前page對(duì)象關(guān)聯(lián)的paginator對(duì)象;
                
方法
        has_next()
                判斷是否有下一頁(yè)乙埃,如果有返回True闸英;
                
        has_previous()
                判斷是否有上一頁(yè),如果有返回True介袜;
                
        has_other_pages()
                判斷是否有上一頁(yè)或者下一頁(yè)甫何,如果有返回True;
                
        next_page_number()
                返回下一頁(yè)的頁(yè)碼遇伞,如故下一頁(yè)不存在辙喂,拋出InvalidPage異常;
                
        previous_page_number()
                返回上一頁(yè)的頁(yè)碼,如故上一頁(yè)不存在巍耗,拋出InvalidPage異常秋麸;
                
        len()
                返回當(dāng)前頁(yè)的數(shù)據(jù)個(gè)數(shù);

4.3 Paginator對(duì)象與Page對(duì)象的關(guān)系

Paginator對(duì)象 把 Student.object.all() 返回的列表分割炬太;
使用 Paginator對(duì)象的 page方法灸蟆,生成對(duì)應(yīng)列表段的 Page對(duì)象;
每個(gè)Page對(duì)象亲族,對(duì)應(yīng)列表段中的內(nèi)容炒考;

4.4 示例:分頁(yè)顯示學(xué)生信息

studentpage.html
    <ul><li>{{ pagenum }}</li></ul>
    <ul>
        {% for stu in student %}
            <li>{{ stu.id }} | {{ stu.sname }} | {{ stu.sgrade }}</li>
        {% endfor %}
    </ul>
    <ul>
        {% for index in student.paginator.page_range %}
        {# 調(diào)用page對(duì)象的paginator方法,到達(dá)paginator類孽水;#}
        {# 再使用paginator類的page_range方法票腰;#}
            <li><a href="/studentpage/{{ index }}/">{{ index }}</a></li>
        {% endfor %}
    </ul>
    
views.py
        from django.core.paginator import Paginator
        def studentpage(request, pageid):
            # 所有學(xué)生的列表
            allList = Student.stuObj.all()
            paginator = Paginator(allList, 3)
            page = paginator.page(pageid)
            pagenum = page.number
            return render(request, 'myapp/studentpage.html', {"student": page, "pagenum": pagenum})

urls.py
        url(r'^studentpage/(\d+)/$', views.studentpage),

5 ajax

需要?jiǎng)討B(tài)生成,請(qǐng)求json數(shù)據(jù)

栗子:
        views.py
                from django.http import JsonResponse
                def ajaxstudet(request):
                    stus = Student.stuObj.all()
                    list = []
                    for stu in stus:
                        list.append([stu.id, stu.sname, stu.sgrade])
                    return JsonResponse({"data": list})

6 富文本

pip install django-tinymce

在站點(diǎn)中使用
        配置settings.py文件
                在INSTALLED_APPS中添加:'tinymce',
                在末尾追加:
                        # 富文本
                        TINYMCE_DEFAULT_CONFIG = {
                            'theme': 'advanced',
                            'width': 600,
                            'height': 400,
                        }
                        
        創(chuàng)建一個(gè)模型類(myApp/models.py):
                from tinymce.models import HTMLField
                class Text(models.Model):
                    str = HTMLField()
                    
        配置站點(diǎn)(myApp/admin.py):
                from .models import Text
                admin.site.register(Text)
                

在自定義視圖中使用
        urls.py
                url(r'^edit/$', views.edit),
                
        views.py
                def edit(request):
                    return render(request, 'myApp/edit.html')
                    
        edit.html
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>富文本</title>
                    <script type="text/javascript" src="/static/tiny_mce/tiny_mce.js"></script>
                    <script type="text/javascript">
                        tinyMCE.init({
                            'mode': 'textareas',
                            'theme': 'advanced',
                            'width': 600,
                            'height': 400,
                        })
                    </script>
                </head>
                <body>
                <form action="">
                    <textarea name="str">lance is good man</textarea>
                    <input type="submit" value="提交">
                </form>
                </body>
                </html>

7 celery

http://docs.jinkan.org/docs/celery/

問(wèn)題:
        1. 用戶發(fā)起request女气,并且要等待response返回杏慰;但是在視圖中有一些耗時(shí)的操作,導(dǎo)致用戶可能會(huì)等待很長(zhǎng)時(shí)間才能接受response炼鞠,這樣用戶體驗(yàn)很差缘滥;
        
        2. 網(wǎng)站每隔一段時(shí)間要同步數(shù)據(jù),但是http請(qǐng)求是需要觸發(fā)的谒主;


celery解決:
        問(wèn)題1: 將耗時(shí)的操作朝扼,放到celery中執(zhí)行;
        問(wèn)題2: 使用celery定時(shí)執(zhí)行霎肯;


celery組件:
        任務(wù)tasl        本質(zhì)是一個(gè)Python函數(shù)擎颖,將耗時(shí)操作封裝成一個(gè)函數(shù);
        隊(duì)列queue       將要執(zhí)行的任務(wù)观游,放到隊(duì)列里搂捧;
        工人woeker      負(fù)責(zé)執(zhí)行隊(duì)列中的任務(wù);
        代理broker       負(fù)責(zé)調(diào)度懂缕,在部署環(huán)境中使用redies;


安裝:
        pip install celery
        pip install celery-with-redis
        pip install django-celery
       
        
配置settings.py:
        INSTALLED_APPS
                'djcelery',
                
        追加
                import djcelery
                djcelery.setup_loader()     #初始化
                BROKER_URL = 'redis://:user@IP:6379/0'
                CELERY_IMPORTS = ('myApp.task',)
            
               
創(chuàng)建task.py
        project/myApp/task.py


遷移允跑,生成celery需要的數(shù)據(jù)庫(kù)表:
        python manage.py migrate


在 /project/project 下創(chuàng)建 celery.py:
        from __future__ import absolute_import
        import os
        from celery import Celery
        from django.conf import settings
        
        os.environ.setdefault( 'DJANGO_SETTINGS_MODULES', 'whthas_home.settings')
        app = Celery('portal')
        
        app.config_from_onject('django.conf:settings')
        app.authodiscover_tasks(lambda: settings.INSTALLED_APPS)
        
        @app.task(bind=True)
        def debug_task(self):
        print('Request: {0!r}'.format(self.request))


在project/project/__init__.py中添加:
    from .celery import import app as celery_app
    









?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市搪柑,隨后出現(xiàn)的幾起案子聋丝,更是在濱河造成了極大的恐慌,老刑警劉巖工碾,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弱睦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡倚喂,警方通過(guò)查閱死者的電腦和手機(jī)每篷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門瓣戚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人焦读,你說(shuō)我怎么就攤上這事子库。” “怎么了矗晃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵仑嗅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我张症,道長(zhǎng)仓技,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任俗他,我火速辦了婚禮脖捻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘兆衅。我一直安慰自己地沮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布羡亩。 她就那樣靜靜地躺著摩疑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪畏铆。 梳的紋絲不亂的頭發(fā)上雷袋,一...
    開(kāi)封第一講書(shū)人閱讀 52,682評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音辞居,去河邊找鬼楷怒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛瓦灶,可吹牛的內(nèi)容都是我干的率寡。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼倚搬,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了乾蛤?” 一聲冷哼從身側(cè)響起每界,我...
    開(kāi)封第一講書(shū)人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎家卖,沒(méi)想到半個(gè)月后眨层,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡上荡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年趴樱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了馒闷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡叁征,死狀恐怖纳账,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捺疼,我是刑警寧澤疏虫,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站啤呼,受9級(jí)特大地震影響卧秘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜官扣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一翅敌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惕蹄,春花似錦蚯涮、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至赶促,卻和暖如春液肌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸥滨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工嗦哆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人婿滓。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓老速,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親凸主。 傳聞我的和親對(duì)象是個(gè)殘疾皇子橘券,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361