今天就跟大家聊聊有關(guān)如何在Django中使用celery和NGINX生成靜態(tài)頁面,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
創(chuàng)新互聯(lián)長期為近1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為江州企業(yè)提供專業(yè)的網(wǎng)站設(shè)計制作、成都網(wǎng)站建設(shè),江州網(wǎng)站改版等技術(shù)服務(wù)。擁有10多年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。性能優(yōu)化原理:
當(dāng)我們要給client瀏覽器返回一個頁面時,我們需要去數(shù)據(jù)庫查詢數(shù)據(jù)并將數(shù)據(jù)和基本頁面模板渲染形成頁面返回給客戶端,但如果每一個用戶訪問時都去查詢一次首頁的的數(shù)據(jù)時,當(dāng)日訪問量很大時那么無疑會給數(shù)據(jù)庫查詢帶來很大的性能問題。為了解決這個問題,我們可以給未登錄用戶返回一個早就渲染好的靜態(tài)首頁(給已登錄的用戶返回一個調(diào)用緩存數(shù)據(jù)和個人數(shù)據(jù)渲染的頁面),這樣就可以提高網(wǎng)站的性能了。
使用celery生成靜態(tài)首頁
生成靜態(tài)頁面原理:
在一個為靜態(tài)首頁準(zhǔn)備的基礎(chǔ)模板之上,獲取數(shù)據(jù),使用django的loader加載基礎(chǔ)模板,使用render渲染頁面即可生成幾臺頁面。
安裝celery
pip install celery
為redis配置settings文件
# diango的緩存配置 CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/9", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } }
準(zhǔn)備一個首頁靜態(tài)模板文件static_base.html
{# 首頁 注冊 登錄 #} <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> {% load staticfiles %} <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> {# 網(wǎng)頁標(biāo)題內(nèi)容塊 #} <title>{% block title %}{% endblock title %}</title> <link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}"> <link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}"> {# 網(wǎng)頁頂部引入文件塊 #} {% block topfiles %}{% endblock topfiles %} </head> <body> {# 網(wǎng)頁頂部歡迎信息塊 #} {% block header_con %} <div class="header_con"> <div class="header"> <div class="welcome fl">歡迎來到商城!</div> <div class="fr"> <div class="login_btn fl"> <a href="{% url 'user:login' %}">登錄</a> <span>|</span> <a href="{% url 'user:register' %}">注冊</a> </div> <div class="user_link fl"> <span>|</span> <a href="{% url 'user:user' %}">用戶中心</a> <span>|</span> <a href="cart.html">我的購物車</a> <span>|</span> <a href="{% url 'user:order' %}">我的訂單</a> </div> </div> </div> </div> {% endblock header_con %} {# 網(wǎng)頁頂部搜索框塊 #} {% block search_bar %} <div class="search_bar clearfix"> <a href="index.html" class="logo fl"><img src="{% static 'images/logo.png' %}"></a> <div class="search_con fl"> <input type="text" class="input_text fl" name="" placeholder="搜索商品"> <input type="button" class="input_btn fr" name="" value="搜索"> </div> <div class="guest_cart fr"> <a href="#" class="cart_name fl">我的購物車</a> <div class="goods_count fl" id="show_count">{{ cart_count }}</div> </div> </div> {% endblock search_bar %} {# 網(wǎng)站主體內(nèi)容塊 #} {% block body %}{% endblock body %} <div class="footer"> <div class="foot_link"> <a href="#">關(guān)于我們</a> <span>|</span> <a href="#">聯(lián)系我們</a> <span>|</span> <a href="#">招聘人才</a> <span>|</span> <a href="#">友情鏈接</a> </div> <p>CopyRight © 2016 北京商城信息技術(shù)有限公司 All Rights Reserved</p> <p>電話:010-****888 京ICP備*******8號</p> </div> {# 網(wǎng)頁底部html元素塊 #} {% block bottom %}{% endblock bottom %} {# 網(wǎng)頁底部引入文件塊 #} {% block bottomfiles %}{% endblock bottomfiles %} </body> </html>
在首頁靜態(tài)模板文件的基礎(chǔ)上繼承生成一個首頁靜態(tài)文件 static_index.html 方便celery獲取數(shù)據(jù)庫文件并進(jìn)行渲染
{% extends 'static_base.html' %} {% load staticfiles %} {% block title %}首頁{% endblock title %} {% block topfiles %} <script type="text/javascript" src="{% static 'js/jquery-1.12.4.min.js' %}"></script> <script type="text/javascript" src="{% static 'js/jquery-ui.min.js' %}"></script> <script type="text/javascript" src="{% static 'js/slide.js' %}"></script> {% endblock topfiles %} {% block body %} <div class="navbar_con"> <div class="navbar"> <h2 class="fl">全部商品分類</h2> <ul class="navlist fl"> <li><a href="">首頁</a></li> <li class="interval">|</li> <li><a href="">手機生鮮</a></li> <li class="interval">|</li> <li><a href="">抽獎</a></li> </ul> </div> </div> <div class="center_con clearfix"> <ul class="subnav fl"> {% for type in types %} <li><a href="#model0{{ forloop.counter }}" class="{{ type.logo }}">{{ type.name }}</a></li> {% endfor %} </ul> <div class="slide fl"> <ul class="slide_pics"> {% for banner in goods_banners %} <li><a href="#"><img src="{{ banner.image.url }}" alt="幻燈片"></a></li> {% endfor %} </ul> <div class="prev"></div> <div class="next"></div> <ul class="points"></ul> </div> <div class="adv fl"> {% for banner in promotion_banners %} <a href="{{ banner.url }}"><img src="{{ banner.image.url }}"></a> {% endfor %} </div> </div> {% for type in types %} <div class="list_model"> <div class="list_title clearfix"> <h4 class="fl" id="model0{{ forloop.counter }}">{{ type.name }}</h4> <div class="subtitle fl"> <span>|</span> {% for banner in type.title_banners %} <a href="#">{{ banner.sku.name }}</a> {% endfor %} </div> <a href="#" class="goods_more fr" id="fruit_more">查看更多 ></a> </div> <div class="goods_con clearfix"> <div class="goods_banner fl"><img src="{{ type.image.url }}"></div> <ul class="goods_list fl"> {% for banner in type.image_banners %} <li> <h5><a href="#">{{ banner.sku.name }}</a></h5> <a href="#"><img src="{{ banner.sku.image.url }}"></a> <div class="prize">¥ {{ banner.sku.price }}</div> </li> {% endfor %} </ul> </div> </div> {% endfor %} {% endblock body %}
在項目下新建celery_tasks文件夾,在文件夾中新建tasks.py文件, 編寫tasks文件 ;
from django.conf import settings from celery import Celery from django.template import loader # 在任務(wù)處理者一端加這幾句 import os # import django # os.environ.setdefault("DJANGO_SETTINGS_MODULE", "shoppingmall.settings") # django.setup() # 這幾個類要放在django環(huán)境初始化那四句的下面 from goods.models import GoodsType, IndexGoodsBanner, IndexPromotionBanner, IndexTypeGoodsBanner # 創(chuàng)建一個Celery類的實例對象 app = Celery('celery_tasks.tasks', broker='redis://127.0.0.1:6379/8') @app.task def generate_static_index_html(): '''產(chǎn)生首頁靜態(tài)頁面''' # 獲取商品的種類信息 types = GoodsType.objects.all() # 獲取首頁輪播商品信息 goods_banners = IndexGoodsBanner.objects.all().order_by('index') # 獲取首頁促銷活動信息 promotion_banners = IndexPromotionBanner.objects.all().order_by('index') # 獲取首頁分類商品展示信息 for type in types: # GoodsType # 獲取type種類首頁分類商品的圖片展示信息 image_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=1).order_by('index') # 獲取type種類首頁分類商品的文字展示信息 title_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=0).order_by('index') # 動態(tài)給type增加屬性,分別保存首頁分類商品的圖片展示信息和文字展示信息 type.image_banners = image_banners type.title_banners = title_banners # 組織模板上下文 context = { 'types': types, 'goods_banners': goods_banners, 'promotion_banners': promotion_banners } # 使用模板 # 1.加載模板文件,返回模板對象 temp = loader.get_template('static_index.html') # 2.模板渲染 static_index_html = temp.render(context) # 生成首頁對應(yīng)靜態(tài)文件 save_path = os.path.join(settings.BASE_DIR, 'static/index.html') with open(save_path, 'w', encoding='utf-8') as f: f.write(static_index_html)
開啟redis服務(wù)
E:\>cd E:\YifChanSoft\Database\Redis\RedisSoft\Redis-x64-3.2.100 E:\YifChanSoft\Database\Redis\RedisSoft\Redis-x64-3.2.100>redis-server --service-install redis.windows-service.conf --loglevel verbose E:\YifChanSoft\Database\Redis\RedisSoft\Redis-x64-3.2.100>redis-cli 127.0.0.1:6379> select 8 OK 127.0.0.1:6379[8]> keys * 1) "_kombu.binding.celery" 2) "_kombu.binding.celery.pidbox" 127.0.0.1:6379[8]>
開啟redis服務(wù)截圖
將項目代碼拷貝一份放在某處,進(jìn)入該處, 啟動tasks的worker模式 ,
注意,用作worker的代碼的tasks文件中應(yīng)該有提前啟動django的初始化的代碼,不然worker沒法調(diào)用conf信息;
即應(yīng)該有以下內(nèi)容
# 在任務(wù)處理者一端加這幾句 import os import django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "shoppingmall.settings") django.setup()
為了解決celery4.x在win10上運行的錯誤,安裝eventlet
pip install eventlet
進(jìn)入復(fù)制用來做celery工作者的項目代碼所在處
開啟worker模式
celery -A celery_tasks.tasks worker -l info -P eventlet
開啟worker模式截圖
如果有就刪除celery代碼文件中static中的index.html文件;
主動調(diào)用 generate_static_index_html.delay() 即可驗證生成index.html;
from celery_tasks.tasks import generate_static_index_html generate_static_index_html.delay()
驗證截圖
可以看到在項目下的static文件夾下生成了index.html;
開啟項目在瀏覽器中輸入 http://127.0.0.1:8888/static/index.html/ 即可看到生成的靜態(tài)首頁;因為數(shù)據(jù)庫中還沒有數(shù)據(jù),所以頁面比較空。
NGINX的安裝
參考教程: https://www.jb51.net/article/171374.htm
1.下載nginx: http://nginx.org/en/download.html
2.解壓縮nginx包
下載好后在放入合適的目錄,解壓縮后如下
3.使用cmd命令,進(jìn)入nginx所在解壓縮目錄,使用如下命令進(jìn)行 安裝nginx ;
start nginx.exe
安裝截圖
安裝完成后,我們可以在 任務(wù)管理器中看到nginx任務(wù),如圖
至此,nginx就算安裝完成了。
nginx命令
start nginx.exe # 開啟nginx nginx -s reload # 重新啟動 nginx -s stop # 停止nginx nginx -s quit # 退出nginx
使用NGINX提供靜態(tài)首頁
修改nginx配置
找到nginx的配置文件,如下圖所示,為了方便以后其他的項目使用,我們拷貝一份源文件重命名為nginx_origin.conf
用編輯器打開 nginx.conf 文件,修改配置文件中內(nèi)容如下:
location /static { alias E:/Pycharm/Pycharm_save/cp15/18Django_fresh3/step206/shoppingmall206/static/; } location / { # root html; root E:/Pycharm/Pycharm_save/cp15/18Django_fresh3/step206/shoppingmall206/static/; index index.html index.htm; }
配置截圖
注意,其中的地址應(yīng)該是你使用celery的項目所在的絕對路徑地址,并且地址之間應(yīng)該使用斜杠/而不是反斜杠\,否則會報錯。
修改好配置保存后,我們使用一下命令進(jìn)行nginx的重啟
nginx -s reload
然后,我們打開瀏覽器輸入一下兩個鏈接之一就可以看到項目主頁面了。
http://127.0.0.1/ # 注意,后面必須有一個/,否則會進(jìn)入nginx默認(rèn)界面 http://127.0.0.1/static/index.html
項目主頁面截圖
nginx的cmd命令截圖,其中的報錯都是因為使用的是win10目錄自帶的反斜杠
在Django網(wǎng)站和celery可以理解是并列的關(guān)系,在他們之前,其實還有一個nginx服務(wù)器負(fù)責(zé)調(diào)度;
一般是當(dāng)用戶直接訪問127.0.0.1時,我們通過nginx調(diào)度去celery的nginx中返回靜態(tài)頁面;
而當(dāng)用戶訪問127.0.0.1/index時,我們返回調(diào)用Django網(wǎng)站的IndexView;
在網(wǎng)站上線時我們會使用nginx對它們進(jìn)行配置。
后臺數(shù)據(jù)修改時重新生成靜態(tài)頁面
原理
在數(shù)據(jù)庫的數(shù)據(jù)改變時,會調(diào)用admin.ModelAdmin下的sava_model和delete_model方法用來更新數(shù)據(jù),而我們需要當(dāng)數(shù)據(jù)改變后重新生成靜態(tài)頁面;
因此,我們可以自定義一個類繼承admin.ModelAdmin,重寫更新和刪除數(shù)據(jù)的方法,調(diào)用父類的更新刪除方法后,調(diào)用celery中的方法重新生成靜態(tài)首頁;
實現(xiàn)
我們要配置當(dāng)某個表的數(shù)據(jù)改變時重新生成靜態(tài)頁面,就要給該表定義一個 xxxModelAdmin 類,繼承自admin.ModelAdmin并重寫其中的方法,并且在admin中注冊時該表應(yīng)該同時繼承xxxModelAdmin 類;
因為有很多表都需要如此配置,且類中的代碼都相同,所以我們可以抽出一個 BaseModelAdmin 類,編寫更新后重新調(diào)用生成靜態(tài)頁面的代碼,然后讓各個需要修改的表繼承該類即可。
在首頁對應(yīng)的應(yīng)用中的admin.py文件中編寫如下代碼
from django.contrib import admin # from django.core.cache import cache from goods.models import GoodsType, GoodsSKU, Goods, GoodsImage, IndexGoodsBanner, IndexTypeGoodsBanner, IndexPromotionBanner from celery_tasks.tasks import generate_static_index_html class BaseModelAdmin(admin.ModelAdmin): """當(dāng)后臺數(shù)據(jù)庫數(shù)據(jù)改動時使celery重新生成靜態(tài)首頁頁面""" def save_model(self, request, obj, form, change): """當(dāng)更新或者新增數(shù)據(jù)時調(diào)用""" super().save_model(request, obj, form, change) # 發(fā)出任務(wù),讓celery worker重新生成靜態(tài)首頁 generate_static_index_html.delay() # 清除首頁的緩存數(shù)據(jù) # cache.delete("index_page_data") def delete_model(self, request, obj): """當(dāng)刪除數(shù)據(jù)時調(diào)用""" super().delete_model(request, obj) generate_static_index_html.delay() # 清除首頁的緩存數(shù)據(jù) # cache.delete("index_page_data") class GoodsTypeAdmin(BaseModelAdmin): pass class IndexGoodsBannerAdmin(BaseModelAdmin): pass class IndexTypeGoodsBannerAdmin(BaseModelAdmin): pass class IndexPromotionBannerAdmin(BaseModelAdmin): pass admin.site.register(GoodsType, GoodsTypeAdmin) admin.site.register(GoodsSKU) admin.site.register(Goods) admin.site.register(GoodsImage) admin.site.register(IndexGoodsBanner, IndexGoodsBannerAdmin) admin.site.register(IndexTypeGoodsBanner, IndexTypeGoodsBannerAdmin) admin.site.register(IndexPromotionBanner, IndexPromotionBannerAdmin)
看完上述內(nèi)容,你們對如何在Django中使用celery和NGINX生成靜態(tài)頁面有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。
文章標(biāo)題:如何在Django中使用celery和NGINX生成靜態(tài)頁面-創(chuàng)新互聯(lián)
當(dāng)前網(wǎng)址:http://vcdvsql.cn/article16/ceoggg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、網(wǎng)頁設(shè)計公司、網(wǎng)站導(dǎo)航、App開發(fā)、關(guān)鍵詞優(yōu)化、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容