Django’s use celery and NGINX generate static page performance optimization

Performance optimization principle:

When we give the client browser returns a page, we need to query the data and database data and basic page template when the page is returned to the client, but they all go home once a query of data if each user access rendering form, the day when a lot of traffic that will undoubtedly bring a lot of database query performance issues. To solve this problem, we can return to the user is not logged in already rendered a good static home (to return a user has logged in cache data and personal data rendered page calls), so that you can improve the performance of the website.


Use celery generate static Home

Principle generate static pages:

On the basis of a template prepared for static home page, access data, using the django loader The basic template using render rendering the page to generate a few pages.

Installation celery

pip install celery

Configuration settings file to redis


diango cache configuration

CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } }

Prepare a Home static template file static_base.html

{# 首页 注册 登录 #}
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="" xml:lang="en">
{% load staticfiles %}
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    {# 网页标题内容块 #}
    <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' %}">
    {# 网页顶部引入文件块 #}
    {% block topfiles %}{% endblock topfiles %}
{# 网页顶部欢迎信息块 #}
{% 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>
                    <a href="{% url 'user:register' %}">注册a>
                <div class="user_link fl">
                    <a href="{% url 'user:user' %}">用户中心a>
                    <a href="cart.html">我的购物车a>
                    <a href="{% url 'user:order' %}">我的订单a>
{% endblock header_con %}

{# 网页顶部搜索框块 #}
{% 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

= "Search products"

> <input type="button" class="input_btn fr" name="" value

= "Search"

> 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 %} {# 网站主体内容块 #} {% block body %}{% endblock body %} <div class="footer"> <div class="foot_link"> <a href="#">关于我们a> <span>|span> <a href="#">联系我们a> <span>|span> <a href="#">招聘人才a> <span>|span> <a href="#">友情链接a> div> <p>CopyRight © 2016 北京商城信息技术有限公司 All Rights Reservedp> <p>电话:010-****888 京ICP备*******8号p> div> {# 网页底部html元素块 #} {% block bottom %}{% endblock bottom %} {# 网页底部引入文件块 #} {% block bottomfiles %}{% endblock bottomfiles %} body> html>


On the basis of a static template file Home succession to generate a static file static_index.html Home celery convenient access to the database file and render

{% 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">
            <h1 class="fl">全部商品分类h1>
            <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>

    <div class="center_con clearfix">
        <ul class="subnav fl">
            {% for type in types %}
                <li><a href="#model0{{ forloop.counter }}" class="{{ type.logo }}">{{ }}a>li>
            {% endfor %}
        <div class="slide fl">
            <ul class="slide_pics">
                {% for banner in goods_banners  %}
                    <li><a href="#"><img src="{{ banner.image.url }}" alt

= "Slide"

>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"> <h3 class="fl" id="model0{{ forloop.counter }}">{{ }}h3> <div class="subtitle fl"> <span>|span> {% for banner in type.title_banners %} <a href="#">{{ }}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> <h4><a href="#">{{ }}a>h4> <a href="#"><img src="{{ banner.sku.image.url }}">a> <div class="prize">¥ {{ banner.sku.price }}div> li> {% endfor %} ul> div> div> {% endfor %} {% endblock body %}


New celery_tasks folder under the project, in the folder New files, documents written tasks;

from django.conf import settings
from celery import Celery
from django.template import loader


In the end the task handler added these words

import os # import django # os.environ.setdefault("DJANGO_SETTINGS_MODULE", "shoppingmall.settings") # django.setup() #

These classes should be placed django environment initialization that four of the following

from goods.models import GoodsType, IndexGoodsBanner, IndexPromotionBanner, IndexTypeGoodsBanner #

Create an instance of a class Celery

app = Celery('celery_tasks.tasks', broker='redis://') @app.task def generate_static_index_html(): '''

Generating static pages Home

''' #

Obtain information on the type of goods

types = GoodsType.objects.all() #

Home Carousel obtain product information

goods_banners = IndexGoodsBanner.objects.all().order_by('index') #

Gets Home Promotion Information

promotion_banners = IndexPromotionBanner.objects.all().order_by('index') #

Home Categories get merchandise display information

for type in types: # GoodsType #

Home Categories get the kind of type of commodity information Photo Gallery

image_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=1).order_by('index') #

Home types of classification of goods acquired type of text information display

title_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=0).order_by('index') #

Dynamic to increase the property type, classification of goods were stored images Home display information and text information display

type.image_banners = image_banners type.title_banners = title_banners #

Organization template context

context = { 'types': types, 'goods_banners': goods_banners, 'promotion_banners': promotion_banners } #

Using Templates


1. load the template file, return template object

temp = loader.get_template('static_index.html') #

2. Render Template

static_index_html = temp.render(context) #

Home generates a corresponding static files

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)

Open redis service

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 --loglevel verbose

E:\YifChanSoft\Database\Redis\RedisSoft\Redis-x64-3.2.100>redis-cli> select 8
OK[8]> keys *
1) "_kombu.binding.celery"
2) "_kombu.binding.celery.pidbox"[8]>

Screenshot turn redis service

The project code copy somewhere, enter the premises, start tasks of worker model, note, used as a file code of worker’s tasks should have started django initialization code in advance, otherwise the worker can not conf call information;

That should have the following


In the end the task handler added these words

import os import django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "shoppingmall.settings") django.setup()

In order to resolve the error celery4.x run on win10, installation eventlet

pip install eventlet

Enter the copy used to make celery workers at the project code resides

Open mode worker

celery -A celery_tasks.tasks worker -l info -P eventlet

Screenshot mode is turned on worker

Then remove the index.html file celery code file in static; the initiative to call generate_static_index_html.delay () to verify that the generated index.html;

from celery_tasks.tasks import generate_static_index_html

Verification screenshot


We can see the static files in the project folder created under the index.html;

Enter the project open in your browser to see generated static home; because there is no data in the database, it is relatively empty page.


NGINX installation

Tutorial: https: //

1. Download nginx: http: //

2. Extract the package nginx

Once you have downloaded into the appropriate directory, unzip the following

3. cmd command, enter nginx where unzipped, using the following command to install nginx;

start nginx.exe

Installation screenshots

After installation is complete, we can see the nginx task in Task Manager, as

So far, nginx even if the installation is complete.


nginx command

start nginx.exe  #

Open nginx

nginx -s reload #


nginx -s stop #

Stop nginx

nginx -s quit #

Exit nginx


Use NGINX provide static Home

Modify the configuration nginx

Find nginx configuration file, as shown below, in order to facilitate future use of other projects, we copy the source file is renamed nginx_origin.conf

Nginx.conf open file editor, modify the configuration file as follows:

location /static {
    alias E:/Pycharm/Pycharm_save/cp15/18Django_fresh2/step206/shoppingmall206/static/;

location / {
    # root   html;
    root   E:/Pycharm/Pycharm_save/cp15/18Django_fresh2/step206/shoppingmall206/static/;
    index  index.html index.htm;

Configuration Screenshot

Note where the address should be the absolute path you use celery project is located, and address should be used between slashes / instead of the backslash \, otherwise it will error.


Once you’ve modified the configuration saved, we use the following command to restart the nginx

nginx -s reload

We then point your browser at one of the two links you can see the main page of the project.  #

Note that must be followed by a /, otherwise it will default interface enter nginx

Project main page screenshot


nginx cmd command of shots, which are being given because using win10 directory comes with a backslash

In Django site can be understood and celery are juxtaposed relationship, before they, in fact, there is a nginx server is responsible for scheduling; generally when the user direct access to, we go through the schedule celery nginx nginx returned the static page; and when a user accesses, we return to the calling Django site IndexView;

We will use nginx time line on the site to configure them.


Regenerate static page when the background data modification


When data in the database changes, and will call sava_model delete_model method under admin.ModelAdmin used to update the data, and we need to re-generate static pages when the data changes;

Therefore, we can customize a class that inherits admin.ModelAdmin, update, and delete data rewriting method, call the update method to delete the parent class, the method celery in a call to re-generate static home;



We want to regenerate the configuration of static page when the data changes in a table, it is necessary to define the table a xxxModelAdmin class, inherited from admin.ModelAdmin and method in which the rewrite, and the table should inherit xxxModelAdmin simultaneously registered in the admin class;

Because there are so many tables are required to configure and class codes are the same, so we can extract a BaseModelAdmin class, recall the generated code static pages after writing the update, and then let each table needs to be modified to extend this class.

Write the following code in the application file corresponding home

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):

When the back-end database data changes in the celery regenerate static home page

""" def save_model(self, request, obj, form, change): """

Called when new or updated data

""" super().save_model(request, obj, form, change) #

Issued a task, let celery worker to re-generate static Home

generate_static_index_html.delay() #

Home Clear cache data

# cache.delete("index_page_data") def delete_model(self, request, obj): """

When data is deleted, call

""" super().delete_model(request, obj) generate_static_index_html.delay() #

Clear cache data from the home page

# cache.delete("index_page_data") class GoodsTypeAdmin(BaseModelAdmin): pass class IndexGoodsBannerAdmin(BaseModelAdmin): pass class IndexTypeGoodsBannerAdmin(BaseModelAdmin): pass class IndexPromotionBannerAdmin(BaseModelAdmin): pass, GoodsTypeAdmin), IndexGoodsBannerAdmin), IndexTypeGoodsBannerAdmin), IndexPromotionBannerAdmin)

At this point, when we will re-generate the static home in the admin background update data, you can try it on their own –


Leave a Reply