07-Django高級(jí)使用

一、靜態(tài)文件

  • 簡(jiǎn)述
CSS、JS陶夜、JSON桃序、圖片、字體文件...
  • 配置settings.py
STATIC_URL='/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]
  • 示例
{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>餓了嗎 | 首頁</title>
    <link rel="stylesheet" type="text/css" href="{% static 'elema/css/style.css' %}"/>
    <script type="text/javascript" src="{% static 'elema/js/jquery-3.1.1.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'elema/js/index.js' %}"></script>
</head>

<body>
    <h1>餓了嗎溯职?</h1>
    <img src="{% static 'elema/img/1.jpeg' %}">
</body>

</html>

在項(xiàng)目文件中創(chuàng)建static精盅,并創(chuàng)建對(duì)應(yīng)的應(yīng)用目錄,在應(yīng)用目錄里面添加例如js谜酒、img叹俏、css等目錄

二、中間件

  • 概述
    中間件是一個(gè)用來處理Django的請(qǐng)求和響應(yīng)的框架級(jí)別的鉤子僻族。
    它是一個(gè)輕量粘驰、低級(jí)別的插件系統(tǒng),用于在全局范圍內(nèi)改變Django的輸入和輸出述么。
    每個(gè)中間件組件都負(fù)責(zé)做一些特定的功能蝌数。
    但是由于其影響的是全局,所以需要謹(jǐn)慎使用顶伞,使用不當(dāng)會(huì)影響性能枝哄。

本質(zhì): 就是一個(gè)python類
應(yīng)用場(chǎng)景: 統(tǒng)計(jì)挠锥、黑名單侨赡、白名單、反爬...

  • 方法
- __init__
    不需要傳參蓖宦,服務(wù)器響應(yīng)第一個(gè)請(qǐng)求的時(shí),會(huì)自動(dòng)調(diào)用稠茂,用于確定是否啟用中間件
- process_request(self,request)
    在視圖執(zhí)行前調(diào)用(即分配url匹配視圖之前),每個(gè)請(qǐng)求都會(huì)調(diào)用柠偶,返回None或HttpResponse對(duì)象
- process_view(self,request,view_func,view_args,view_kwargs)
    調(diào)用視圖之前執(zhí)行,每個(gè)請(qǐng)求都會(huì)調(diào)用,返回None或HttpResponse對(duì)象
- process_templae_response(self,request,response)
    在視圖剛好執(zhí)行完后調(diào)用睬关,每個(gè)請(qǐng)求都會(huì)調(diào)用诱担,返回None或HttpResponse對(duì)象
- process_response(self,request,response)
    所有響應(yīng)返回瀏覽器之前調(diào)用,每個(gè)請(qǐng)求都會(huì)調(diào)用电爹,返回None或HttpResponse對(duì)象
- process_exception(self,request,exception)
    當(dāng)視圖出現(xiàn)異常時(shí)調(diào)用蔫仙,返回HttpResponse對(duì)象
    
備注: 為什么會(huì)返回HttpRespons對(duì)象?因?yàn)樵谡?qǐng)求進(jìn)來后如果有問題丐箩,就可以不做后續(xù)處理摇邦,直接給客戶端響應(yīng)。

settings.py中的MIDDLEWARE = [...]就中間件屎勘。

  • 方法執(zhí)行


    中間件方法執(zhí)行.png
  • 自定義中間件并使用

在工程目錄下middleware目錄下創(chuàng)建應(yīng)用目錄
- 在middleware/elema中創(chuàng)建一個(gè)elemamiddleware.py
from django.utils.deprecation import MiddlewareMixin
class MyMiddle(MiddlewareMixin):
    # 在視圖執(zhí)行前調(diào)用
    def process_request(self,reqeust):
        print('get請(qǐng)求施籍,參數(shù)name: ', reqeust.GET.get('name'))

- 配置settings.py文件(即在MIDDLEWARE中添加上述文件的位置)
    'middleware.elema.elemamiddleware.MyMiddle'

- 瀏覽器
    http://127.0.0.1:8000/?name=zyz

- 效果  
    在終端中可以看到`get請(qǐng)求,參數(shù)name:  zyz`
  • 中間件(黑名單攔截)
# 攔截器挑秉,攔截他黑名單中的IP
class MyMiddle(MiddlewareMixin):
    def process_request(self, request):
      if request.META['REMOTE_ADDR'] in getattr(settings, 'BLOCKED_IPS', []):
        return HttpResponse('<h1>Forbidden</h1>')

# settings.py中
BLOCKED_IPS = [  # IP黑名單
    '192.168.0.100'
]
  • 中間件(未登陸處理)
class MyMiddle(MiddlewareMixin):
    def process_request(self, request):
        # request.META['REMOTE_ADDR']  請(qǐng)求的IP地址
        if request.path !='/meituan/login/': # 檢測(cè)如果不是登錄的話
            if "username" in request.COOKIES:   # 已經(jīng)登錄不做任何處理
                pass
            else:   # 未登錄法梯,重定向到登錄頁面
                return HttpResponseRedirect('/meituan/login/')

三、上傳圖片

  • 注意
- 文件上傳時(shí)犀概,文件數(shù)據(jù)存儲(chǔ)在request.FILES屬性中
- form表單要上傳文件需要加 enctype="multipart/form-data"
- 上傳文件必須是post請(qǐng)求
  • 存儲(chǔ)路徑
- 在static目錄下創(chuàng)建upfile目錄用于存儲(chǔ)接受上傳的文件
- 配置settings.py文件
    MDEIA_ROOT = os.path.join(BASE_DIR,'static/upfile')
  • 示例
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上傳</title>
</head>
<body>
    <form action="{% url 'elema:savefile' %}" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="file" value="上傳文件" name="file">
        <input type="submit" value="上傳">
    </form>
</body>
</html>
# 文件上傳
def upfile(request):
    return render(request, 'elema/upfile.html')

# 文件保存
import os
from django.conf import settings    # 導(dǎo)入settings.py
def savefile(request):
    # 判斷是否為POST
    if request.method == 'POST':
        # 獲取文件內(nèi)容
        file = request.FILES['file']
        # 文件保存路徑
        filepath = os.path.join(settings.MDEIA_ROOT,file.name)
        # 文件寫入
        with open(filepath,'wb') as fp:
            for info in file.chunks():
                fp.write(info)
        return HttpResponse('文件上傳成功')
    else:
        return HttpResponse('文件上傳失敗')

四、分頁

  • Paginator創(chuàng)建對(duì)象
格式: Paginator(列表,每頁個(gè)數(shù))
返回值: 分頁對(duì)象
  • Paginator屬性
count: 對(duì)象總數(shù)
num_pages: 頁面總數(shù)
page_range: 頁碼列表(頁碼從1開始)
  • Paginator方法
page(num): 獲得一個(gè)Page對(duì)象,如果提供的頁面不存在會(huì)拋出'InvalidPage'異常
  • Paginator異常
InvalidPage: 當(dāng)向page()傳遞是一個(gè)無效頁碼時(shí)拋出
PageNotAnInteger: 當(dāng)向page()傳遞的不是一個(gè)整數(shù)時(shí)拋出
EmptyPage: 當(dāng)向page()傳遞一個(gè)有效值这嚣,但該頁面沒有數(shù)據(jù)時(shí)拋出
  • Page創(chuàng)建對(duì)象
Paginator對(duì)象的page()方法返回得到Page對(duì)象(不需要手動(dòng)創(chuàng)建)
  • Page屬性
object_list: 當(dāng)前頁上所有的數(shù)據(jù)(對(duì)象)列表
number: 當(dāng)前頁的頁碼值
paginator: 當(dāng)前page對(duì)象關(guān)聯(lián)的paginator對(duì)象
  • Page方法
has_next(): 判斷是否有下一頁障涯,如果有返回True
has_previous(): 判斷是否有上一頁九秀,如果有返回True
has_other_pages(): 判斷是否有上一頁或下一頁痹换,如果有返回True
next_page_number(): 返回下一頁的頁碼缔杉,如果下一頁不存在拋出InvalidPage異常
previous_page_number(): 返回上一頁的頁碼,如果上一頁不存在拋出InvalidPage異常
len(): 返回當(dāng)前頁的數(shù)據(jù)(對(duì)象)個(gè)數(shù)
  • Paginator對(duì)象與Page對(duì)象關(guān)系
  • 示例
# urls.py文件
url(r'^goodslist/(\d+)/$',views.goodslist, name='goodslist'), # 商品列表 
# views.py文件
# 商品列表
from .models import Goods
from django.core.paginator import Paginator
def goodslist(request,page):
    # 所有商品數(shù)據(jù)
    alllist = Goods.objects.all()

    # 10條數(shù)據(jù)為一頁,劃分總頁數(shù)
    # 分頁對(duì)象
    paginator = Paginator(list(alllist),10)

    # 根據(jù)傳入的頁碼得到Page對(duì)象
    pageobj = paginator.page(page)

    # return HttpResponse('page:'+page)
    return render(request,'elema/goodslist.html',{'pageobj':pageobj})
# models.py文件
# 商品 模型類
class Goods(models.Model):
    # 商品名稱
    name = models.CharField(max_length=20)
    # 商品圖片
    icon = models.CharField(max_length=255)
    # 商品價(jià)格
    price = models.IntegerField()
    # 商品描述
    detail = models.CharField(max_length=255)

    class Meta:
        db_table = 'goods' 
# 存儲(chǔ)過程: 創(chuàng)建商品數(shù)據(jù)(產(chǎn)生批量數(shù)據(jù))
# 第一步: 創(chuàng)建上述Goods模型類 【注意表名是goods】
# 第二步: 生成遷移文件,并執(zhí)行遷移
# 第三步: 進(jìn)入到對(duì)應(yīng)的數(shù)據(jù)庫中,檢查表單結(jié)構(gòu)是否一致
mysql> desc goods;
+--------+--------------+------+-----+---------+----------------+
| Field  | Type         | Null | Key | Default | Extra          |
+--------+--------------+------+-----+---------+----------------+
| id     | int(11)      | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)  | NO   |     | NULL    |                |
| icon   | varchar(255) | NO   |     | NULL    |                |
| price  | int(11)      | NO   |     | NULL    |                |
| detail | varchar(255) | NO   |     | NULL    |                |
+--------+--------------+------+-----+---------+----------------+
# 第四步: 將圖片 'cymbal.png'等,放置在'/static/img'目錄

# 第五步: 創(chuàng)建 存儲(chǔ)過程 添加到數(shù)據(jù)庫中(復(fù)制到mysql終端中)
# insert into elema_goods(name,icon,price,detail) value(_name,_icon,_price,_detail)
delimiter //
create procedure add_goods(num int(4))
begin
    # 定義變量
    declare _i,_price,_temp int(4) default 0;
    declare _name,_icon,_detail varchar(255) default '';
    declare BASE_PATH varchar(255) default '/static/img/';

    # 循環(huán)
    while _i<num do
        # 設(shè)置變量
        set _temp = round(rand()*10000+1000);
        set _name = concat(_temp,'-商品名稱');
        set _temp = round(rand()*5+1);
        case _temp
        when 1 then
            set _icon = concat(BASE_PATH,'1.jpg');
        when 2 then
            set _icon = concat(BASE_PATH,'2.jpg');
        when 3 then
            set _icon = concat(BASE_PATH,'3.jpg');
        when 4 then
            set _icon = concat(BASE_PATH,'4.jpg');
        when 5 then
            set _icon = concat(BASE_PATH,'5.jpg');
        when 6 then
            set _icon = concat(BASE_PATH,'6.jpg');
        else
            set _icon = concat(BASE_PATH,'1.jpg');
        end case;
        set _temp = round(rand()*10000+1000);
        set _price = _temp;
        set _temp = round(rand()*10000+1000);
        set _detail = concat(_temp,'-Apple/蘋果 iPhone 7 Plus蘋果7代7pluss國行美版三網(wǎng)5.5寸7p手機(jī)');

        # 插入數(shù)據(jù)
        insert into goods(name,icon,price,detail) value(_name,_icon,_price,_detail);

        # 修改次數(shù)
        set _i = _i + 1;
    end while;

    # 顯示數(shù)據(jù)
    select * from goods;
end
//
delimiter ;


# 第六步: 調(diào)用存儲(chǔ)過程 【根據(jù)自己需求添加對(duì)應(yīng)個(gè)數(shù)即可】
call add_goods(30);
# goodslist.html文件
{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>餓了嗎 | 商品列表</title>
    <link rel="stylesheet" type="text/css" href="{% static 'elema/css/goodslist.css' %}">
</head>
<body>
    <h1>當(dāng)前頁: {{pageobj.number}}</h1>

    <!--顯示內(nèi)容-->
    <ul class="content">
        {% for goods in pageobj.object_list %}
            <li>
                <div>
                    <img src="{{goods.icon}}">
                    <span> {{goods.name}} - ¥{{goods.price}}</span>
                </div>
                <p> {{goods.detail}} </p>
            </li>
        {% endfor %}
    </ul>

    <!--分頁頁碼-->
    <ul class="pageview">
        {% for index in pageobj.paginator.page_range %}
            <!--當(dāng)前頁面-->
            {% if index == pageobj.number %}
                <li class="active"> {{index}} </li>
            {% else %}
                <li>
                    <a href="{% url 'elema:goodslist' index %}">{{index}}</a>
                </li>
            {% endif %}
        {% endfor %}
    </ul>
</body>
</html>

五、ajax請(qǐng)求

  • 概述
網(wǎng)頁中需要?jiǎng)討B(tài)生成時(shí),會(huì)向服務(wù)器請(qǐng)求對(duì)應(yīng)JSON數(shù)據(jù)
  • 示例
# urls.py文件
url(r'^goodsjson/$',views.goodsjson, name='goodsjson'), # 商品列表json數(shù)據(jù)操作頁面(ajax操作)
url(r'^goodsinfo/$',views.goodsinfo, name='goodsinfo'), # 商品列表json數(shù)據(jù)
# views.py文件
# 商品列表json數(shù)據(jù)(ajax操作)
def goodsjson(request):
    return render(request,'elema/goodsjson.html')
    
# 返回商品列表json數(shù)據(jù)
from django.http import JsonResponse
def goodsinfo(request):
    # 所有商品數(shù)據(jù)
    alllist = Goods.objects.all()

    # 拼接成列表
    list = []
    for goods in alllist:
        list.append({'name':goods.name,'price':goods.price})

    return JsonResponse({'data':list})
# goodsjson.html文件
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>商品列表JSON數(shù)據(jù)</title>
    <script type="text/javascript" src="{% static 'elema/js/jquery-3.1.1.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'elema/js/goodsjson.js' %}"></script>
</head>

<body>
    <h1>商品信息列表</h1>
    <button id="bt">顯示商品列表</button>

</body>

</html>
# goodsjson.js文件
$(function(){
    $('#bt').click(function(){
        // jquery中ajax快捷操作
        $.ajax({
            type:"get",
            url:"/elema/goodsinfo",
            dataType: 'json',
            success: function(data, status){
                console.log(data);
                
                // 獲取返回的數(shù)據(jù)
                var datasource = data['data'];
                
                for(var i=0; i<datasource.length; i++){
                    var oP = document.createElement('p');
                    oP.innerHTML = datasource[i]['name'] + "  ¥" + datasource[i]['price'];
                    document.body.appendChild(oP);
                }
            }
        });
    });
});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末饺饭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子扛芽,更是在濱河造成了極大的恐慌,老刑警劉巖叮喳,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剩晴,死亡現(xiàn)場(chǎng)離奇詭異毅整,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)承粤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門彻舰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來隔心,“玉大人硬霍,你說我怎么就攤上這事“莨欤” “怎么了橄碾?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)眉枕。 經(jīng)常有香客問我,道長(zhǎng)姥宝,這世上最難降的妖魔是什么腊满? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任省咨,我火速辦了婚禮穷缤,結(jié)果婚禮上津肛,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好搪花,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著幢踏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪搭幻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天俯逾,我揣著相機(jī)與錄音堡赔,去河邊找鬼灼捂。 笑死宫蛆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播忿薇,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼筋栋,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼二汛!你這毒婦竟也來了渣磷?” 一聲冷哼從身側(cè)響起醋界,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎提完,沒想到半個(gè)月后形纺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡徒欣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年逐样,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脂新。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出介杆,到底是詐尸還是另有隱情,我是刑警寧澤褒脯,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站虎锚,受9級(jí)特大地震影響柱徙,放射性物質(zhì)發(fā)生泄漏长赞。R本人自食惡果不足惜热幔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一留瞳、第九天 我趴在偏房一處隱蔽的房頂上張望前硫。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瞭吃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國打工集峦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓脖咐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親咪奖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子盗忱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 面試報(bào)名 4月18日—21日 面試考試 5月20日—21日
    貓七_(dá)698b閱讀 82評(píng)論 0 0
  • 這個(gè)暑假我去了,老家羊赵。我們做了很長(zhǎng)時(shí)間的車趟佃。到了那后我就去我外婆家。坐一坐昧捷,玩一會(huì)兒闲昭,然后就在那住了下來 還有我奶...
    啦啦啦啦啦我是賣報(bào)的小玩家閱讀 382評(píng)論 0 0
  • 愛情,剛開始或許是一種吸引靡挥,一種外貌的吸引序矩,久而久之,便是一種舒適跋破。沒有刻意的討好簸淀,沒有刻意的委屈。
    馮凡平閱讀 171評(píng)論 0 1
  • 【青春校園】我不怕孤身一人,只怕沒有你(目錄) 璇子本來想到了搭上地鐵之后再跟陳辰講她下班的消息的拧簸,所以陳辰發(fā)信息...
    薄小荷閱讀 268評(píng)論 8 7