Django之admin管理数据库,cookie验证及分页设置

一、admin管理数据库

1)models.py创建class类表

class Book(models.Model):
    name=models.CharField(max_length=20)
    price=models.IntegerField()
    pub_date=models.DateField()
    publish=models.ForeignKey("Publish")
    authors=models.ManyToManyField("Author")    # 会自动生成多对多的book_author的关系表

    def __str__(self):
        return self.name

class Publish(models.Model):
    name=models.CharField(max_length=32)
    city=models.CharField(max_length=32)

    def __str__(self):
        return self.name

class Author(models.Model):
    name=models.CharField(max_length=32)
    age=models.IntegerField(default=20)

    def __str__(self):
        return self.name
models.py

 强调:配置文件加入app,  LANGUAGE_CODE = 'zh-hans' 修改后台显示语言

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser     生成管理员账号及密码

2)运行Django,输入http://127.0.0.1:8000/admin。

 

 

 3)添加admin管理model创建的表

name=models.CharField(max_length=20,verbose_name="姓名")  起别名
price=models.IntegerField("价格")   # 起别名
from django.contrib import admin
from admin_orm import models
# Register your models here.

admin.site.register(models.Author)
admin.site.register(models.Book)
admin.site.register(models.Publish)
admin.py

 

 4)自定义admin管理models表

from django.contrib import admin
from admin_orm import models
# Register your models here.

# 自定义表的后台管理
class BookAdmin(admin.ModelAdmin):
    list_display = ('id','name','price','pub_date')
    # 字段横着显示,字段显示不能加多对多的字段

    list_editable = ('name','price')        # 横着显示,修改字段
    filter_horizontal = ('authors',)         # 添加字段内容的搜索框
    list_per_page = 5          # 分页,显示数据的长度,默认是20条
    search_fields = ('id','name','publish__name')
    # 按照字段搜索,publish__name因为关联了别的表,所有以 publish的name搜索

    list_filter = ('pub_date','publish')    # 过滤
    ordering = ("price",'id')   # 排序
    # filter_vertical =    # 垂直的,
    # fieldsets =[
    #     (None,               {'fields': ['title']}),
    #     ('price information', {'fields': ['price',"publisher"], 'classes': ['collapse']}),
    # ]         # 隐藏增加属性

admin.site.register(models.Author)
admin.site.register(models.Book,BookAdmin)      #  引用自定义的后台管理表内容
admin.site.register(models.Publish)
admin.py

 

二、学生信息管理(自定义网站管理(数据库))

1)创建学生信息表

from django.db import models

# Create your models here.
class Classes(models.Model):
    '''
    班级表,与老师是 一对多的关系
    '''
    titile = models.CharField(max_length=32)
    m = models.ManyToManyField("Teachers")

class Teachers(models.Model):
    '''
    老师表
    '''
    name = models.CharField(max_length=32)

class Student(models.Model):
    '''
    学生表,班级是一对多的关系
    '''
    username = models.CharField(max_length=32)
    age = models.IntegerField()
    gender = models.BooleanField()
    cs = models.ForeignKey(Classes)
models.py

2)编辑前端文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <a href="/add_classes.html">添加</a>
    </div>
    <div>
        <table border="1">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>名称</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                {% for row in cls_list %}
                    <tr>
                        <td>
                            {{ row.id }}
                        </td>
                        <td>
                            {{ row.titile}}
                        </td>
                        <td>
                            <a href="/del_classes.html?nid={{ row.id }}">删除</a>
                            |
                            <a href="/edit_classes.html?nid={{ row.id }}">编辑</a>
                        </td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
    </div>
</body>
</html>
get_classes.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="add_classes.html" method="POST">
        {% csrf_token %}
        <input type="text" name="title">
        <input type="submit" value="提交">
    </form>


</body>
</html>
add_classes.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="POST" action="/edit_classes.html?nid={{ obj.id }}">
        {% csrf_token %}
        <input type="text" name="xxoo" value="{{ obj.titile }}"/>
        <input type="submit" value="提交" />
    </form>
</body>
</html>
edit_classes.html

 3)定义路由

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^classes.html',classes.get_classes),
    url(r'^add_classes.html',classes.add_classes),
    url(r'^del_classes.html', classes.del_classes),
    url(r'^edit_classes.html', classes.edit_classes),
]
urls.py

4)创建视图函数

from django.shortcuts import render,redirect
from app01 import models
# Create your views here.

def get_classes(request):
    cls_list = models.Classes.objects.all()
    return render(request,'get_classes.html',{'cls_list':cls_list})

def add_classes(request):
    if request.method == "GET":
        return render(request,'add_classes.html')
    elif request.method == "POST":
        title = request.POST.get('title')
        models.Classes.objects.create(titile=title)
        return redirect('/classes.html')

def del_classes(request):
    nid = request.GET.get('nid')
    models.Classes.objects.filter(id = nid).delete()
    return redirect('/classes.html')


def edit_classes(request):
    if request.method == 'GET':
        nid = request.GET.get('nid')
        obj = models.Classes.objects.filter(id=nid).first()
        return render(request,'edit_classes.html',{'obj':obj})
    elif request.method == 'POST':
        nid = request.GET.get('nid')
        title = request.POST.get('xxoo')
        models.Classes.objects.filter(id=nid).update(titile=title)
        return redirect('/classes.html')
views.classes.py

5)展示效果

 

三、用户登录验证

Django版本的不同,可能需要在settings.py 修改 MIDDLEWARE  为  MIDDLEWARE_CLASS

1)Django的cookie验证

准备html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>

<form action="/login/" method="post">
    <p>姓名<input type="text" name="user"></p>
    <p>密码<input type="password" name="pwd"></p>
    <p><input type="submit"></p>
</form>

</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
<h1>{{ name }}</h1>
</body>
</html>
index.html

由于是post的请求

配置文件注释这一行  # 'django.middleware.csrf.CsrfViewMiddleware',

准备url

from django.conf.urls import url
from django.contrib import admin
from admin_orm import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^index/', views.index),
]
urls.py

 视图函数cookie验证原理

from django.shortcuts import render,redirect

# Create your views here.

def login(request):
    print("COOKIES",request.COOKIES)    # 查看cookie
    if request.method == "POST":
        name = request.POST.get("user")
        pwd = request.POST.get("pwd")
        print(name,pwd)
        if name == "user" and pwd =="123":
            ret = redirect("/index/")
            ret.set_cookie("blili",'acfine')    # 第一次登陆发送给客户端cookie值
            # ret.set_cookie("username",name)
            return ret
    return render(request,'login.html')


def index(request):
    if request.COOKIES.get("blili",None) == "acfine":       # 第二次登录,携带cookie值
    # if request.COOKIES.get("username", None) == "yuan":
        name = "yuan"
        return render(request, 'index.html',locals())
    else:
        return redirect("/login/")
views.py

 简单优化cookie验证,name = request.COOKIES.get("username",None)

from django.shortcuts import render,redirect

# Create your views here.

def login(request):
    print("COOKIES",request.COOKIES)    # 查看cookie
    if request.method == "POST":
        name = request.POST.get("user")
        pwd = request.POST.get("pwd")
        print(name,pwd)
        if name == "user" and pwd =="123":
            ret = redirect("/index/")
            ret.set_cookie("username",{""})
            return ret
    return render(request,'login.html')


def index(request):

    if request.COOKIES.get("username", None):
        name = request.COOKIES.get("username",None)
        return render(request, 'index.html',locals())
    else:
        return redirect("/login/")
views.py

2)Django的cookie与session配合实现验证

from django.shortcuts import render,redirect

# Create your views here.
import datetime
expires = datetime.datetime.utcnow()+datetime.timedelta(days=3)
def login(request):
    print("COOKIES",request.COOKIES)    # 查看cookie
    print("SESSION",request.session)
    if request.method == "POST":
        name = request.POST.get("user")
        pwd = request.POST.get("pwd")
        print(name,pwd)
        if name == "user" and pwd =="123":
            # ret = redirect("/index/")
            # ret.set_cookie("username",{"11":"22"},
            #                max_age=10,  # max_age=10  有效时间10秒,找不到就找后面个
            #                expires = datetime.datetime.utcnow()+datetime.timedelta(days=3))     # 有效时间3天,
            # return ret

            # COOKIE SESSION,session默认在服务端保存15天
            request.session["is_login"] = True
            request.session["user"] = name
            return redirect("/index/")

    return render(request,'login.html')


def index(request):
    # if request.COOKIES.get("username", None):
    #     name = request.COOKIES.get("username",None)
    #     return render(request, 'index.html',locals())

    if request.session.get("is_login",None):
        name = request.session.get('user',None)
        return render(request,"index.html",locals())
    else:
        return redirect("/login/")
views.py

 四、jquery的Ajax应用。不知觉的往后台发请求,而不刷新页面

1)前端文件写入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .btn{
            display: inline-block;
            padding: 5px 15px;
            background: darkgoldenrod;
            color: white;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div>
        <input placeholder="用户名" type="text" id="username">
        <input placeholder="密码" type="password" id="password">
        <div class="btn" onclick="submitForm();">提交</div>
    </div>
    <div>
        <input placeholder="数字" type="text" id="i1">
        <input placeholder="数字" type="text" id="i2">
        <div class="btn" onclick="addForm();">等于</div>
        <input placeholder="数字" type="text" id="i3">
    </div>
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script>
        function submitForm() {
            var u = $('#username').val();
            var p = $('#password').val();
            console.log(u, p);
            $.ajax({
                url: '/ajax2.html',
                type: 'GET',
                data:{username:u,password:p},
                success:function (arg) {
                    console.log(arg);
                }
            })
        }


        function addForm(){
            var v1 = $('#i1').val();
            var v2 = $('#i2').val();
            $.ajax({
                url:'/ajax3.html',
                type:'POST',
                data:{"v1":v1,"v2":v2},
                success:function(arg){
                    console.log(arg);
                    $('#i3').val(arg)
                    //window.location.reload(); //页面刷新
                }
            })
        }
    </script>
</body>
</html>
ajax1.html

2)路由写入

urlpatterns = [
    url(r'^admin/', admin.site.urls),


    url(r'^ajax1.html$', ajax.ajax1),
    url(r'^ajax2.html$', ajax.ajax2),
    url(r'^ajax3.html$', ajax.ajax3),
]
urls.py

3)视图文件写入

def ajax1(request):
    return render(request,'ajax1.html')


def ajax2(request):
    user = request.GET.get('username')
    pwd = request.GET.get('password')
    import time
    time.sleep(5)
    return HttpResponse('DSB')

def ajax3(request):
    v1 = request.POST.get('v1')
    v2 = request.POST.get('v2')
    try:
        v3 = int(v1) + int(v2)
    except Exception as e:
        v3 = "输入格式有误"
    return HttpResponse(v3)
view_ajax.py

 五、分页功能

1)简单的模拟分页

 第一步:分页准备

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for row in user_list %}
            <li>{{ row.name }}-{{ row.age }}</li>
        {% endfor %}
    </ul>
</body>
</html>
index.html

  url(r'^index.html$',views.index)

USER_LIST = []
for i in range(1,999):
    temp = {'name':'root'+str(i),'age':i}
    USER_LIST.append(temp)

def index(request):
    return render(request,'index.html',{'user_list':USER_LIST})
views.py

 第二步:调整url,简单的显示分页功能

USER_LIST = []
for i in range(1,999):
    temp = {'name':'root'+str(i),'age':i}
    USER_LIST.append(temp)

def index(request):
    per_page_count = 10
    current_page = request.GET.get('p')
    current_page= int(current_page)
    start = (current_page-1) * per_page_count
    end = current_page * per_page_count
    data = USER_LIST[start:end]
    return render(request,'index.html',{'user_list':data})
views.py

 手动修改url的p值来修改分页显然不现实

2)分页功能实现上一页,下一页展示

修改html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for row in user_list %}
            <li>{{ row.name }}-{{ row.age }}</li>
        {% endfor %}
    </ul>
    <a href="/index.html?p={{ prev_pager }}">上一页</a>
    <a href="/index.html?p={{ next_pager }}">下一页</a>
</body>
</html>
index.html

修改视图函数

USER_LIST = []
for i in range(1,999):
    temp = {'name':'root'+str(i),'age':i}
    USER_LIST.append(temp)

def index(request):
    per_page_count = 10
    current_page = request.GET.get('p')
    current_page= int(current_page)

    start = (current_page-1) * per_page_count
    end = current_page * per_page_count
    data = USER_LIST[start:end]

    prev_pager = current_page -1
    next_pager = current_page +1
    return render(request,'index.html',{
        'user_list':data,
        'prev_pager':prev_pager,
        'next_pager':next_pager
    })
views.py

3)Django的内置分页设计

 3.1)增加视图函数

def index1(request):
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    # 全部数据:USER_LIST, ==>得出共有多少条数据
    # per_page: 每页显示条目数量
    # count: 数据总个数
    # num_pages:总页数
    # page_range:总页数的索引范围,如:(110),(1,200)
    # page: page对象(是否具有下一页,是否有上一页)
    current_page = request.GET.get('p')
    paginator = Paginator(USER_LIST,10)
    try:
        posts = paginator.page(current_page)
        # has_next              是否有下一页
        # next_page_number      下一页页码
        # has_previous          是否有上一页
        # previous_page_number  上一页页码
        # object_list           分页之后的数据列表
        # number                当前页
        # paginator             paginator对象
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts=paginator.page(paginator.num_pages)
    return render(request, 'index1.html',{'posts':posts})
views.index1

    3.2)添加相应的html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for row in posts.object_list %}
            <li>{{ row.name }}-{{ row.age }}</li>
        {% endfor %}
    </ul>
    {% if posts.has_previous %}
        <a href="/index1.html?p={{ posts.previous_page_number }}">上一页</a>
        {% else %}
        <a href="#">上一页</a>
    {% endif %}
    {% if posts.has_next %}
        <a href="/index1.html?p={{ posts.next_page_number }}">下一页</a>
    {% endif %}
    <span>
        {{ posts.number }} / {{ posts.paginator.num_pages }}
    </span>
</body>
</html>
index1.html

    3.3)分页功能提取出来,减少代码冗余

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for row in posts.object_list %}
            <li>{{ row.name }}-{{ row.age }}</li>
        {% endfor %}
    </ul>
    {% include 'include/pager.html' %}

</body>
</html>
index1.html

  添加 include/pager.html 页面

{% if posts.has_previous %}
    <a href="/index1.html?p={{ posts.previous_page_number }}">上一页</a>
    {% else %}
    <a href="#">上一页</a>
{% endif %}
{% if posts.has_next %}
    <a href="/index1.html?p={{ posts.next_page_number }}">下一页</a>
{% endif %}
<span>
    {{ posts.number }} / {{ posts.paginator.num_pages }}
</span>
pager.html

 3.4)自定义类,实现自定义分页功能

修改视图

USER_LIST = []
for i in range(1,689):
    temp = {'name':'root'+str(i),'age':i}
    USER_LIST.append(temp)

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
class CustomPaginator(Paginator):
    def __init__(self,current_page,per_pager_num,*args,**kwargs):
        self.current_page = int(current_page)   # 当前页
        self.per_pager_num = int(per_pager_num) # 最多显示的页面数量
        super(CustomPaginator,self).__init__(*args,**kwargs)

    def pager_num_range(self):
        if self.num_pages < self.per_pager_num:
            return range(1,self.num_pages+1)

        # 总页数特别多 5
        part = int(self.per_pager_num/2)
        if self.current_page <=part:
            return range(1,self.per_pager_num+1)

        if (self.current_page +part) > self.num_pages:
            return range(self.num_pages-self.per_pager_num+1,self.num_pages+1)

        return range(self.current_page - part, self.current_page + part + 1)

def index1(request):
    # 全部数据:USER_LIST, ==>得出共有多少条数据
    # per_page: 每页显示条目数量
    # count: 数据总个数
    # num_pages:总页数
    # page_range:总页数的索引范围,如:(110),(1,200)
    # page: page对象(是否具有下一页,是否有上一页)
    current_page = request.GET.get('p')
    paginator = CustomPaginator(current_page,11,USER_LIST,10)
    try:
        posts = paginator.page(current_page)
        # has_next              是否有下一页
        # next_page_number      下一页页码
        # has_previous          是否有上一页
        # previous_page_number  上一页页码
        # object_list           分页之后的数据列表
        # number                当前页
        # paginator             paginator对象
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts=paginator.page(paginator.num_pages)
    return render(request, 'index1.html',{'posts':posts})
views.py

修改分页前端代码

{% if posts.has_previous %}
    <a href="/index1.html?p={{ posts.previous_page_number }}">上一页</a>
    {% else %}
    <a href="#">上一页</a>
{% endif %}

{% for i in posts.paginator.pager_num_range %}
    {% if i == posts.number %}
        <a style="font-size: 30px;" href="/index1.html?p={{ i }}">{{ i }}</a>
    {% else %}
        <a href="/index1.html?p={{ i }}">{{ i }}</a>
    {% endif %}
{% endfor %}

{% if posts.has_next %}
    <a href="/index1.html?p={{ posts.next_page_number }}">下一页</a>
{% endif %}
<span>
    {{ posts.number }} / {{ posts.paginator.num_pages }}
</span>
pager.html

 3.5)模块化定制分页

    定制模块,在app01下写入pager.py

#!/usr/bin/env python
#-*-coding: utf8-*-


class Pagination(object):
    def __init__(self,totalCount,currentPage,perPageItemNum=10,maxPageNum=7):
        # 数据总个数
        self.total_count = totalCount
        # 当前页
        try:
            v = int(currentPage)
            if v <= 0:
               v = 1
            self.current_page = v
        except Exception as e:
            self.current_page = 1
        # 每页显示的行数
        self.per_page_item_num = perPageItemNum
        # 最多显示页面
        self.max_page_num = maxPageNum

    def start(self):
        return (self.current_page-1) * self.per_page_item_num

    def end(self):
        return self.current_page * self.per_page_item_num
    @property
    def num_pages(self):
        """
        总页数
        :return:
        """
        # 666
        # 10
        a,b = divmod(self.total_count,self.per_page_item_num)
        if b == 0:
            return a
        return a+1

    def pager_num_range(self):
        # self.num_pages()
        # self.num_pages
        # 当前页
        #self.current_page
        # 最多显示的页码数量 11
        #self.per_pager_num
        # 总页数
        # self.num_pages
        if self.num_pages < self.max_page_num:
            return range(1,self.num_pages+1)
        # 总页数特别多 5
        part = int(self.max_page_num/2)
        if self.current_page <= part:
            return range(1,self.max_page_num+1)
        if (self.current_page + part) > self.num_pages:
            return range(self.num_pages-self.max_page_num+1,self.num_pages+1)
        return range(self.current_page-part,self.current_page+part+1)

    def page_str(self):
        page_list = []

        first = "<li><a href='/index2.html?p=1'>首页</a></li>"
        page_list.append(first)

        if self.current_page == 1:
            prev = "<li><a href='#'>上一页</a></li>"
        else:
            prev = "<li><a href='/index2.html?p=%s'>上一页</a></li>" %(self.current_page-1,)
        page_list.append(prev)
        for i in self.pager_num_range():
            if i == self.current_page:
                temp = "<li class='active'><a href='/index2.html?p=%s'>%s</a></li>" %(i,i)
            else:
                temp = "<li><a href='/index2.html?p=%s'>%s</a></li>" % (i, i)
            page_list.append(temp)

        if self.current_page == self.num_pages:
            nex = "<li><a href='#'>下一页</a></li>"
        else:
            nex = "<li><a href='/index2.html?p=%s'>下一页</a></li>" % (self.current_page + 1,)
        page_list.append(nex)

        last = "<li><a href='/index2.html?p=%s'>尾页</a></li>" %(self.num_pages,)
        page_list.append(last)

        return ''.join(page_list)
app01_pager.py

写url路由:url(r'^index2.html$', views.index2),

# 模拟页面内容
USER_LIST = []
for i in range(1,689):
    temp = {'name':'root'+str(i),'age':i}
    USER_LIST.append(temp)


def index2(request):
    from app01.pager import Pagination
    current_page = request.GET.get('p')
    page_obj = Pagination(666,current_page)

    data_list = USER_LIST[page_obj.start():page_obj.end()]
    return render(request,'index2.html',{'data':data_list,'page_obj':page_obj})
views.index2

写入前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/>
</head>
<body>
    <ul>
        {% for row in data %}
            <li>{{ row.name }}-{{ row.age }}</li>
        {% endfor %}
    </ul>
    {% for i in page_obj.pager_num_range %}
        <a href="/index2.html?p={{ i }}">{{ i }}</a>
    {% endfor %}
    <hr/>
index2.html

需要导入js的一个插件

  展示效果

 六、前端网页的继承。{% block content %

1)一个盒子的继承关系体现

 模板网页的编写,备注 {# 注释 #}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>hh</div>
    <div>
        {# 私有的部分 #}
        {% block content %}     {# content随便写,止在定义的变化的部分 #}
        <p>这是一个盒子</p>       {# 继承该页面的,如果定义了该内容会覆盖这里的内容 #}
        {% endblock content %}
    </div>
</body>
</html>
base.html

 继承模板的编写

{% extends "base.html" %}       {# 继承 base.html的内容 #}

{% block content %}     {# 寻找 base.html的content的位置添加这里的内容 #}
    <p>这是index里面的内容</p>
{% endblock  %}
index.html

2)拥有多个盒子的继承,原理还是一样。重用父类代码:{{ block.super }}

 模板网页写入了2个盒子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% block title %}
        <title>Title</title>
    {% endblock %}
</head>
<body>
    <div>hh</div>
    <div>
        {# 私有的部分 #}
        {% block content %}     {# content随便写,止在定义的变化的部分 #}
        <p>这是一个盒子</p>       {# 继承该页面的,如果定义了该内容会覆盖这里的内容 #}
        {% endblock content %}
    </div>
</body>
</html>
base.html

 继承模板的编写

{% extends "base.html" %}       {# 继承 base.html的内容 #}

{% block content %}     {# 寻找 base.html的content的位置添加这里的内容 #}
    <p>这是index里面的内容</p>
    <div>
        {{ block.super }}    {# 寻找 如果父类有内容,加上这行,内容不会被覆盖 #}
    </div>
{% endblock  %}

{% block title %}
    <title>index主页</title>
{% endblock %}
index.html

3)继承模板小结

1)如果你在模版中使用 {% extends %} 标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。
2)在base模版中设置越多的 {% block %} 标签越好。请记住,子模版不必定义全部父模版中的blocks,
    所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。
3)如果你发现你自己在大量的模版中复制内容,那可能意味着你应该把内容移动到父模版中的一个 {% block %} 中。
4)为了更好的可读性,尤其是在盒子套盒子时,给{% endblock %} 标签一个名字 。例如:
    {% block content %}
    ...
    {% endblock content %}

参考链接:https://www.cnblogs.com/yuanchenqi/articles/7629939.html

原文地址:https://www.cnblogs.com/linu/p/9353060.html