• python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)


    昨日内容回顾

    复制代码
    视图函数:
    
    request对象
         request.path  请求路径
         request.GET   GET请求数据  QueryDict  {}
         request.POST  POST请求数据 QueryDict  {}
         request.method 请求方式    </span><span style="color: #800000;">"</span><span style="color: #800000;">GET</span><span style="color: #800000;">"</span>   <span style="color: #800000;">"</span><span style="color: #800000;">POST</span><span style="color: #800000;">"</span><span style="color: #000000;">
         request.is_ajax()       是否是Ajax请求
         request.get_full_path()    包含请求数据的路径
         
    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">响应体字符串</span><span style="color: #800000;">"</span><span style="color: #000000;">)
    
    render  :渲染
        render(request,</span><span style="color: #800000;">"</span><span style="color: #800000;">index.html</span><span style="color: #800000;">"</span><span style="color: #000000;">)
        render(request,</span><span style="color: #800000;">"</span><span style="color: #800000;">index.html</span><span style="color: #800000;">"</span>,{<span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">:name})
    
    redirect: 重定向
        两次请求</span></pre>
    
    复制代码

    render没有第3个参数时,直接读取文件。
    有第3个参数时,判断有没有{}语法,然后替换

    redirect是服务器向浏览器发送302指令,它是2次请求。
    form表单提交时,url变动了。因为它必然会发生一次请求!

    当form表单的action属性为空时,单击提交。它会获取当前url作为action的属性,它和当前url没有任何关系。

    思考题:

    假设访问的是login,login的视图函数代码为:

    def login(request):
        return render(request,'login.html')
    View Code

    访问页面是正常的。

    如果改为这样呢?

    def login(request):
        return redirect('/login/')

    访问页面会是怎样的效果?

    分析一下:

    现在直接访问login页面,看看会不会一直跳转。

    页面提示:重定向次数过多

    模板

    模板:
    
    一 变量 {{}}
       </span>1<span style="color: #000000;"> 深度查询   .
       </span>2<span style="color: #000000;"> 过滤器
         {{now</span>|date:<span style="color: #800000;">"</span><span style="color: #800000;">Y-m-d</span><span style="color: #800000;">"</span><span style="color: #000000;">}}
         {{file_size:filesizeformat}} 
         {{link</span>|<span style="color: #000000;">safe}}
    
    二 标签{</span>% %<span style="color: #000000;">}        
        </span>1<span style="color: #000000;">.
        {</span>% <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> []%<span style="color: #000000;">}
        {{forloop.counter}}
        {{forloop.last}}
        {</span>%endfor%<span style="color: #000000;">}
        </span>2<span style="color: #000000;">.
        {</span>% <span style="color: #0000ff;">if</span>  条件%<span style="color: #000000;">}
        </span>&lt;p&gt;1111&lt;/p&gt;<span style="color: #000000;">
        {</span>%<span style="color: #0000ff;">elif</span>%<span style="color: #000000;">}
        </span>&lt;p&gt;2222&lt;/p&gt;<span style="color: #000000;">
        {</span>%<span style="color: #0000ff;">else</span>%<span style="color: #000000;">}
        </span>&lt;p&gt;3333&lt;/p&gt;<span style="color: #000000;">
        {</span>%endif%<span style="color: #000000;">}
        
        </span>3<span style="color: #000000;"> with
        
        </span>4<span style="color: #000000;"> url
        {</span>% url <span style="color: #800000;">'</span><span style="color: #800000;">别名</span><span style="color: #800000;">'</span> 参数 %<span style="color: #000000;">}
        
        </span>5<span style="color: #000000;">
        {</span>% csrf_token %}</pre>
    
    View Code

    注意:datetime也可以做格式化,比如:

    def login(request):
        import datetime
        now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        return HttpResponse(now)
    View Code

    访问页面输出:

    也就是说,后端可以定义格式,前端也可以定义格式,看你喜欢哪种。

    重点掌握if和for语法,还有csrf_token

    一、模板自定义标签和过滤器

    标签,是为了做一些功能。过滤器,是对斜杠前面的数据做过滤。

    为什么要自定义标签和过滤器?因为自带的不够用,需要结合需求,来自定义。

    自定义标签和过滤器需要执行3个步骤:

    1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
    

    2、在app中创建templatetags模块(模块名只能是templatetags)

    3、创建任意 .py 文件,如:my_tags.py

    自定义过滤器

    举例:增加一个乘法过滤器

    修改settings.py中的INSTALLED_APPS,最后一行添加当前的app。

    django开头的,都是一些自带的app。它内置在django源码里面!

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',
    ]
    View Code

    在app01目录里面新建一个templatetags目录,目录名必须是这个!!!否则django找不到。

    目录里面创建my_filter_tag.py,这个py文件名,可以随便定义。内容如下:

    from django import template
    from django.utils.safestring import mark_safe
    register=template.Library()
    

    @register.filter
    def multi_filter(x,y):
    return x*y

    View Code

    注意:头部的3行,是固定写法,不能改变。

    增加@register.filter,是为了将函数转换成过滤器。函数的名字,可以自定义。

    修改views.py里面的index函数,内容如下:

    def index(request):
        num = 100
        return render(request,'index.html',{'num':num})
    View Code

    修改index.html,修改body部分

    注意:在使用自定义标签和过滤器,必须在html文件中,导入之前创建的my_filter_tag

    {% load my_filter_tag %}
    <p>{{ num|multi_filter:5 }}</p>
    View Code

    load表示导入模块。p标签中的内容,是执行了multi_filter过滤器。

    注意:它接收了2个参数。一个是num,一个是5。因为multi_filter过滤器,定义了2个形参,使用它必须传2个参数才行。

    访问index页面,输出:

    是因为自定义的模块,没有导入成功,提示找不到!为啥呢?因为django项目启动时,会导入settings.py定义的模块导入,由于app01的自定义模块是启动之后加的,所以它并没有加载进去。

    重启django项目,就可以加载了。

    再次访问index,页面输出:

     如果要完成3位乘法呢?过滤器可以增加一个形参,但是index.html怎么加第3个参数呢?

    答案是,它不能加第3个参数。所以只能在后端,将参数形式修改列表,元组,字典等方式,就可以了。

    举例1:计算4*5*6

    修改index视图函数

    def index(request):
        num1 = 4
        num2 = 5
        num3 = 6
        num_list = [num1,num2,num3]
        return render(request,'index.html',{'num_list':num_list})
    View Code

    修改my_filter_tag.py中的过滤器

    @register.filter
    def multi_filter(num_list):
        res = 1
        for i in num_list:
            res*=i
        return res
    View Code

    修改index.html,修改body部分

    {% load my_filter_tag %}
    <p>{{ num_list|multi_filter }}</p>
    View Code

    访问网页,输出:

    举例1:显示a标签

    修改my_filter_tag.py文件,增加link_tag过滤器

    @register.filter
    def link_tag(href):
        return "<a href=%s>click</a>"%href
    View Code

    修改index视图函数

    def index(request):
        link = "http://www.py3study.com/"
        return render(request,'index.html',{'link':link})
    View Code

    修改index.html,修改body部分

    {% load my_filter_tag %}
    <p>{{ link|link_tag }}</p>
    View Code

    访问网页,输出:

    发现结果不是我们想要的,查看浏览器控制台,查看响应体,发现被转义了

    因为django遇到html或者js标签,会转义。它认为是不安全的!那么如何告诉它,是安全的呢?

    需要在过滤器中导入make_safe模块

    修改my_filter_tag.py文件中的link_tag过滤器,完整代码如下:

    使用make_safe方法,告诉django是安全的,不需要转义

    from django import template
    from django.utils.safestring import mark_safe
    register=template.Library()
    

    @register.filter
    def multi_filter(num_list):
    res
    = 1
    for i in num_list:
    res
    *=i
    return res

    @register.filter
    def link_tag(href):
    return mark_safe("<a href=%s>click</a>" % href)

    View Code

    重启django项目,因为网页有缓存,懒得清理了,所以直接重启django项目,见效快! 

    再次访问

    效果就出来了。

    自定义标签

    标签,是为了做一些功能

    举例:4个参数的乘法运算

    修改my_filter_tag.py,增加multi_tag函数

    @register.simple_tag
    def multi_tag(x,y,z):
        return x*y*z
    View Code

    @register.simple_tag表示将函数转换为自定义标签

    修改index.html,修改body部分

    注意:调用标签,使用{% 标签过滤器名 参数1,参数2,参数3... %}

    参数不限,但不能放在if for语句中

    {% load my_filter_tag %}
    <p>{% multi_tag 7 8 9 %}</p>
    View Code

    重启django项目,访问网页,输出:

    自定义标签和自定义过滤器的区别:

    1. 标签,是为了做一些功能。过滤器,是对斜杠前面的数据做过滤。

    2. 标签可以写任意个形参,而过滤器最大只能写2个形参。如果过滤器需要接收多个参数,需要将参数存放在列表,元组,字典等数据中。

    3. 过滤器可以用在if等语句后,标签不可以

    二、模板继承 (extend)

    Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。

    通过从下面的例子开始,可以容易的理解模版继承:

    include

    新建advertise.html,使用Bootstrap构建2个面板

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
    </head>
    <body>
    

    <div class="row">
    <div class="col-md-4">
    <div class="advertise">
    <div class="panel panel-danger">
    <div class="panel-heading">菜单一</div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-success">
    <div class="panel-heading">菜单一</div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    </div>

    &lt;/div&gt;
    

    </div>

    </body>
    </html>

    View Code

    修改urls.py,增加advertise路径

    urlpatterns = [
        path('admin/', admin.site.urls),
        path('index/', views.index),
        path('advertise/', views.advertise),
    ]
    View Code

    修改views.py,增加advertise视图函数

    def advertise(request):
        return render(request, 'advertise.html')
    View Code

    访问url: http://127.0.0.1:8000/advertise/

    如果首页,也想显示左边的菜单栏呢?代码复制一遍?

    这样代码就重复了,使用include,就可以了。

    修改advertise.html,将相同的部分分离处理

    <div class="row">
        <div class="col-md-4">
            <div class="advertise">
                <div class="panel panel-danger">
                    <div class="panel-heading">菜单一</div>
                    <div class="panel-body">
                        Panel content
                    </div>
                </div>
                <div class="panel panel-success">
                    <div class="panel-heading">菜单一</div>
                    <div class="panel-body">
                        Panel content
                    </div>
                </div>
            </div>
    
    &lt;/div&gt;
    

    </div>

    View Code

    修改index.html,使用include导入advertise.html文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
    </head>
    <body>
    {% include 'advertise.html' %}
    </body>
    </html>
    View Code

    访问首页,效果同上。

     extend

     访问博客园的个人博客,发现很多页面,有几处相同的部分。比如右侧的侧边栏,顶部的导航栏,尾部部分...等等。

    那么公共区域,不需要自己重复写,继承下来就可以了!

    举例:图书网页

    编辑index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <style>
            * {
                margin: 0;
                padding: 0;
            }
    
        .header {
             </span>100%<span style="color: #000000;">;
            height: 60px;
            background</span>-color: <span style="color: #008000;">#</span><span style="color: #008000;">369;</span>
    

    }

        .title {
    
            line</span>-<span style="color: #000000;">height: 60px;
            color: white;
            font</span>-weight: 100<span style="color: #000000;">;
            margin</span>-<span style="color: #000000;">left: 20px;
            font</span>-<span style="color: #000000;">size: 20px;
        }
        .container{
            margin</span>-<span style="color: #000000;">top: 20px;
        }
    </span>&lt;/style&gt;
    

    </head>
    <body>
    <div class="header">
    <p class="title">
    路飞学诚
    </p>
    </div>
    <div class="container">
    <div class="row">
    <div class="col-md-3">
    <div class="panel panel-danger">
    <div class="panel-heading">菜单一</div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-success">
    <div class="panel-heading">菜单二</div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-warning">
    <div class="panel-heading">菜单三</div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    </div>
    <div class="col-md-9">
    <div class="jumbotron">
    <h1>Hello, INDEX!</h1>
    <p>...</p>
    <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
    </div>
    </div>
    </div>
    </div>
    </body>
    </html>

    View Code

    访问index页面,输出:

    如果要访问子页面,比如书籍管理和作者管理?

    修改urls.py,增加articles、authors路径

    urlpatterns = [
        path('admin/', admin.site.urls),
        path('index/',views.index),
        path('articles/',views.articles),
        path('authors/',views.authors),
    ]
    View Code

    修改views.py,增加2个视图函数

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

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

    View Code

    新建articles.html,将index.html的代码全部复制粘贴过来,修改中间内容

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <style>
            * {
                margin: 0;
                padding: 0;
            }
    
        .header {
             </span>100%<span style="color: #000000;">;
            height: 60px;
            background</span>-color: <span style="color: #008000;">#</span><span style="color: #008000;">369;</span>
    

    }

        .title {
    
            line</span>-<span style="color: #000000;">height: 60px;
            color: white;
            font</span>-weight: 100<span style="color: #000000;">;
            margin</span>-<span style="color: #000000;">left: 20px;
            font</span>-<span style="color: #000000;">size: 20px;
        }
        .container{
            margin</span>-<span style="color: #000000;">top: 20px;
        }
    </span>&lt;/style&gt;
    

    </head>
    <body>
    <div class="header">
    <p class="title">
    路飞学诚
    </p>
    </div>
    <div class="container">
    <div class="row">
    <div class="col-md-3">
    <div class="panel panel-danger">
    <div class="panel-heading">菜单一</div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-success">
    <div class="panel-heading">菜单二</div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-warning">
    <div class="panel-heading">菜单三</div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    </div>
    <div class="col-md-9">
    <div class="article_list">
    <ul>
    <li>红楼梦</li>
    <li>三国演义</li>
    <li>西游记</li>
    <li>水浒传</li>
    </ul>
    </div>
    </div>
    </div>
    </div>
    </body>
    </html>

    View Code

    访问articles页面,效果如下:

    新建authors.html,将index.html的代码全部复制粘贴过来,修改中间内容

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <style>
            * {
                margin: 0;
                padding: 0;
            }
    
        .header {
             </span>100%<span style="color: #000000;">;
            height: 60px;
            background</span>-color: <span style="color: #008000;">#</span><span style="color: #008000;">369;</span>
    

    }

        .title {
    
            line</span>-<span style="color: #000000;">height: 60px;
            color: white;
            font</span>-weight: 100<span style="color: #000000;">;
            margin</span>-<span style="color: #000000;">left: 20px;
            font</span>-<span style="color: #000000;">size: 20px;
        }
        .container{
            margin</span>-<span style="color: #000000;">top: 20px;
        }
    </span>&lt;/style&gt;
    

    </head>
    <body>
    <div class="header">
    <p class="title">
    路飞学诚
    </p>
    </div>
    <div class="container">
    <div class="row">
    <div class="col-md-3">
    <div class="panel panel-danger">
    <div class="panel-heading">菜单一</div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-success">
    <div class="panel-heading">菜单二</div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-warning">
    <div class="panel-heading">菜单三</div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    </div>
    <div class="col-md-9">
    <div class="author_list">
    <ul>
    <li>曹雪芹</li>
    <li>罗贯中</li>
    <li>吴承恩</li>
    <li>施耐庵</li>
    </ul>
    </div>
    </div>
    </div>
    </div>
    </body>
    </html>

    View Code

    访问authors页面,效果如下:

     

    问题来了,菜单和导航,都是重复的。有了继承,就可以解决这个问题。
    公共部分有,继承的子页面就会有。没有的部分,子页面也不会有。

    这个模版,我们把它叫作 base.html, 它定义了一个可以用于两列排版页面的简单HTML骨架。“子模版”的工作是用它们的内容填充空的blocks。

    在这个例子中, block 标签定义了三个可以被子模版内容填充的block。 block 告诉模版引擎: 子模版可能会覆盖掉模版中的这些位置。

    子模版可能看起来是这样的:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
         <title>title</title>
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <style>
            * {
                margin: 0;
                padding: 0;
            }
    
        .header {
             </span>100%<span style="color: #000000;">;
            height: 60px;
            background</span>-color: <span style="color: #008000;">#</span><span style="color: #008000;">369;</span>
    

    }

        .title {
    
            line</span>-<span style="color: #000000;">height: 60px;
            color: white;
            font</span>-weight: 100<span style="color: #000000;">;
            margin</span>-<span style="color: #000000;">left: 20px;
            font</span>-<span style="color: #000000;">size: 20px;
        }
        .container{
            margin</span>-<span style="color: #000000;">top: 20px;
        }
    </span>&lt;/style&gt;
    

    </head>
    <body>

    <div class="header">
    <p class="title">
    路飞学诚
    </p>
    </div>

    <div class="container">
    <div class="row">
    <div class="col-md-3">
    <div class="panel panel-danger">
    <div class="panel-heading"><a href="http://127.0.0.1:8008/index/">首页</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-success">
    <div class="panel-heading"><a href="http://127.0.0.1:8008/authors/">作者</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-warning">
    <div class="panel-heading"><a href="http://127.0.0.1:8008/articles/">文章管理</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    </div>
    <div class="col-md-9">
    {
    % block content %}

           {</span>% endblock %<span style="color: #000000;">}
        </span>&lt;/div&gt;
    &lt;/div&gt;
    

    </div>

    </body>
    </html>

    View Code

    修改index.html,删除多余的代码。继承base.html

    它是先继承,再填充内容。

    extends 标签是这里的关键。它告诉模版引擎,这个模版“继承”了另一个模版。当模版系统处理这个模版时,首先,它将定位父模版——在此例中,就是“base.html”。

    那时,模版引擎将注意到 base.html 中的三个 block 标签,并用子模版中的内容来替换这些block。根据 blog_entries 的值,输出可能看起来是这样的:

    {% extends 'base.html' %}
    

    {% block content %}
    <div class="jumbotron">
    <h1>Hello, INDEX!</h1>
    <p>...</p>
    <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
    </div>
    {
    % endblock %}

    View Code

    访问index页面,效果如下:

    修改articles.html,继承base.html

    {% extends 'base.html' %}
    

    {% block content %}
    <div class="article_list">
    <ul>
    <li>红楼梦</li>
    <li>三国演义</li>
    <li>西游记</li>
    <li>水浒传</li>
    </ul>
    </div>
    {
    % endblock %}

    View Code

    访问articles页面,效果如下:

    修改authors.html,继承base.html

    {% extends 'base.html' %}
    

    {% block content %}
    <div class="author_list">
    <ul>
    <li>曹雪芹</li>
    <li>罗贯中</li>
    <li>吴承恩</li>
    <li>施耐庵</li>
    </ul>
    </div>
    {
    % endblock %}

    View Code

    访问authors页面,效果如下:

     

    这样,就解决了代码重复问题

    需求,访问不同页面时,更改tile标签的属性

    怎么做呢?很简单,在base.html里面的title标签位置,定义一个block

    在花括号中间的title标签,表示默认值。如果子页面不设置block title,那么显示默认值。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        {% block title %}
         <title>title</title>
        {% endblock title %}
    
    </span>&lt;link rel=<span style="color: #800000;">"</span><span style="color: #800000;">stylesheet</span><span style="color: #800000;">"</span> href=<span style="color: #800000;">"</span><span style="color: #800000;">https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css</span><span style="color: #800000;">"</span><span style="color: #000000;">
          integrity</span>=<span style="color: #800000;">"</span><span style="color: #800000;">sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u</span><span style="color: #800000;">"</span> crossorigin=<span style="color: #800000;">"</span><span style="color: #800000;">anonymous</span><span style="color: #800000;">"</span>&gt;
    &lt;style&gt;
        *<span style="color: #000000;"> {
            margin: 0;
            padding: 0;
        }
    
        .header {
             </span>100%<span style="color: #000000;">;
            height: 60px;
            background</span>-color: <span style="color: #008000;">#</span><span style="color: #008000;">369;</span>
    

    }

        .title {
    
            line</span>-<span style="color: #000000;">height: 60px;
            color: white;
            font</span>-weight: 100<span style="color: #000000;">;
            margin</span>-<span style="color: #000000;">left: 20px;
            font</span>-<span style="color: #000000;">size: 20px;
        }
        .container{
            margin</span>-<span style="color: #000000;">top: 20px;
        }
    </span>&lt;/style&gt;
    

    </head>
    <body>

    <div class="header">
    <p class="title">
    路飞学诚
    </p>
    </div>

    <div class="container">
    <div class="row">
    <div class="col-md-3">
    <div class="panel panel-danger">
    <div class="panel-heading"><a href="http://127.0.0.1:8008/index/">首页</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-success">
    <div class="panel-heading"><a href="http://127.0.0.1:8008/authors/">作者</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-warning">
    <div class="panel-heading"><a href="http://127.0.0.1:8008/articles/">文章管理</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    </div>
    <div class="col-md-9">
    {
    % block content %}

           {</span>% endblock %<span style="color: #000000;">}
        </span>&lt;/div&gt;
    &lt;/div&gt;
    

    </div>

    </body>
    </html>

    View Code

    修改articles.html,增加一个block

    {% extends 'base.html' %}
    

    {% block content %}
    {{ block.super }}
    <div class="article_list">
    <ul>
    <li>红楼梦</li>
    <li>三国演义</li>
    <li>西游记</li>
    <li>水浒传</li>
    </ul>
    </div>
    {
    % endblock %}

    {% block title %}
    <title>Article</title>
    {
    % endblock %}

    View Code

    访问articles页面,标题就出来了,效果如下:

    访问authors页面,标题就出来了,效果如下:

    由于没有设置block title,它显示默认值。

    现在有一个问题,右侧内容,写死了。比如文章页中的内容
    修改views.py,2个视图,分别增加一个列表

    def articles(request):
        acticle_list = ['红楼梦','三国演义','西游记','水浒传']
        return render(request, 'articles.html',{'acticle_list':acticle_list})
    

    def authors(request):
    author_list
    = ['曹雪芹','罗贯中','吴承恩','施耐庵']
    return render(request, 'authors.html',{'author_list':author_list})

    View Code

    修改修改articles.html,增加一个for循环

    {% extends 'base.html' %}
    

    {% block content %}
    <div class="article_list">
    <ul>
    {
    % for article in acticle_list %}
    <li>{{ article }}</li>
    {
    % endfor %}
    </ul>
    </div>
    {
    % endblock %}

    {% block title %}
    <title>Article</title>
    {
    % endblock %}

    View Code

    修改修改authors.html,增加一个for循环

    {% extends 'base.html' %}
    

    {% block content %}
    <div class="author_list">
    <ul>
    {
    % for author in author_list %}
    <li>{{ author }}</li>
    {
    % endfor %}
    </ul>
    </div>
    {
    % endblock %}

    {% block title %}
    <title>Author</title>
    {
    % endblock %}

    View Code

    重新访问2个页面,效果同上。

    请注意,子模版并没有定义 sidebar block,所以系统使用了父模版中的值。父模版的 {% block %} 标签中的内容总是被用作备选内容(fallback)。

    这种方式使代码得到最大程度的复用,并且使得添加内容到共享的内容区域更加简单,例如,部分范围内的导航。

    这里是使用继承的一些提示:

    • 如果你在模版中使用 {% extends %} 标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。

    举例:下面这种写法是错误的。extends必须在block上面才行。

    {% block content %}
    <div class="jumbotron">
        <h1>Hello, INDEX!</h1>
        <p>...</p>
        <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
    </div>
    {% endblock %}
    

    {% extends 'base.html' %}

    View Code

     访问网页,就会报错

    • 在base模版中设置越多的 {% block %} 标签越好。请记住,子模版不必定义全部父模版中的blocks,所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。

    比如:base.html虽然定义了2个blocks,authors页面可以只继承一个。

    • 如果你发现你自己在大量的模版中复制内容,那可能意味着你应该把内容移动到父模版中的一个 {% block %} 中。

    • If you need to get the content of the block from the parent template, the {{ block.super }} variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using {{ block.super }} will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.

    翻译:

    如果您需要从父模板获取块的内容,则{{block.super}}变量将执行该操作。如果你想添加父块的内容而不是完全覆盖父块的内容,这很有用。使用{{block.super}}插入的数据不会自动转义(请参阅下一节),因为它已经在父模板中被转义(如有必要)。

    举例:

    在base.html中block content里面增加一个h3标签。既系统子页面显示h3标签,同时子标签填充block content里面的内容时,h3标签不会被覆盖。加入一个{{block.super}}就可以了。

    修改base.html,加入h3标签。修改block content部分

    {% block content %}
    <h3>详细内容</h3>
    {% endblock %}

    修改articles.html,在block content 下面一行,增加{{block.super}}

    {% extends 'base.html' %}
    

    {% block content %}
    {{ block.super }}
    <div class="article_list">
    <ul>
    {
    % for article in acticle_list %}
    <li>{{ article }}</li>
    {
    % endfor %}
    </ul>
    </div>
    {
    % endblock %}

    {% block title %}
    <title>Article</title>
    {
    % endblock %}

    View Code

    访问articles页面,效果如下

    注意:如果子页面没有写{{block.super}},那么h3标签就会被覆盖!

    • 为了更好的可读性,你也可以给你的 {% endblock %} 标签一个 名字 。例如:

    {% block content %}
    ...
    {% endblock content %}  

    在大型模版中,这个方法帮你清楚的看到哪一个  {% block %} 标签被关闭了。

    比如base.html中的block title,就是遵循这种写法。

    • 不能在一个模版中定义多个相同名字的 block 标签,否则会被覆盖

    需求:现在的页面是手动跳转的,需要点击菜单时,自动跳转页面。

    修改base.html,增加3个a标签。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        {% block title %}
         <title>title</title>
        {% endblock title %}
    
    </span>&lt;link rel=<span style="color: #800000;">"</span><span style="color: #800000;">stylesheet</span><span style="color: #800000;">"</span> href=<span style="color: #800000;">"</span><span style="color: #800000;">https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css</span><span style="color: #800000;">"</span><span style="color: #000000;">
          integrity</span>=<span style="color: #800000;">"</span><span style="color: #800000;">sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u</span><span style="color: #800000;">"</span> crossorigin=<span style="color: #800000;">"</span><span style="color: #800000;">anonymous</span><span style="color: #800000;">"</span>&gt;
    &lt;style&gt;
        *<span style="color: #000000;"> {
            margin: 0;
            padding: 0;
        }
    
        .header {
             </span>100%<span style="color: #000000;">;
            height: 60px;
            background</span>-color: <span style="color: #008000;">#</span><span style="color: #008000;">369;</span>
    

    }

        .title {
    
            line</span>-<span style="color: #000000;">height: 60px;
            color: white;
            font</span>-weight: 100<span style="color: #000000;">;
            margin</span>-<span style="color: #000000;">left: 20px;
            font</span>-<span style="color: #000000;">size: 20px;
        }
        .container{
            margin</span>-<span style="color: #000000;">top: 20px;
        }
    </span>&lt;/style&gt;
    

    </head>
    <body>

    <div class="header">
    <p class="title">
    路飞学诚
    </p>
    </div>

    <div class="container">
    <div class="row">
    <div class="col-md-3">
    <div class="panel panel-danger">
    <div class="panel-heading"><a href="/index/">首页</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-success">
    <div class="panel-heading"><a href="/authors/">作者</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-warning">
    <div class="panel-heading"><a href="/articles/">文章管理</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    </div>
    <div class="col-md-9">
    {
    % block content %}
    <h3>详细内容</h3>
    {
    % endblock %}
    </div>
    </div>
    </div>

    </body>
    </html>

    View Code

    访问网页,点击左边的连接,就可以任意跳转了。

    效果如下:

    三、Django的模型层-ORM简介

    ORM简介

    ORM,全称是object relation mapping。翻译过来,就是对象关系映射。

    主要来学习MySQL操作,MySQL是一个软件。它的优点:1.免费 2.开源

    pymysql,就是Mysql给Python提供的接口。早期的接口叫mysqldb

    ORM可以实现不写sql语句,就可以实现操作数据库。

    核心是:用python类操作表,用对象操作记录。
    ORM把相应的类和属性操作,转换为sql语句,来操作数据库。它做了一个翻译的过程!

    学习ORM,就是用什么语法,能翻译成什么样的sql语句。

    看下图:

    ORM的优点:

    1.符合python语法。

    2.自己写的sql语句,效率不够高。因为它直接传参,就可以使用了。

    3. 不需要自己写SQL,对于类的操作,会转换成相应的SQL语句,来操作数据库。(核心功能)

    4.它不属于硬编码,它不针对于MySQL。比如公司发展了,需要换成oracle数据库。

    如果项目中的sql语句写死了,那么项目中的所有的sql语句,都得更换。如果用了ORM,只需要改一处,
    直接修改setting.py中的数据库引擎,换成oracle,就可以了。这样,方便数据库迭代,这是它最大的优点。

    ORM的缺点:

    1.执行效率低。看上图,它是从上层到下层的操作。
    它有一个翻译的过程。所以不如直接写SQL操作的执行效率低。
    但是影响不大。真遇到这种请情况,优化SQL就可以了。
    效率问题,跟SQL有很大的关系。


    现在不关心ORM效率问题。除非SQL语句的造诣达到一定级别的时候,就需要使用原生SQL语句。
    orm还提供了,执行原生SQL的接口。可以直接执行原生SQL。

    刚开始写ORM时,一定要对应SQL语句,去写ORM

    • MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动
    • ORM是“对象-关系-映射”的简称。

    上图有一个错误,类型是date,不是data。

    sql中的表

    #sql中的表                                                      
    

    #创建表:
    CREATE TABLE employee(
    id INT PRIMARY KEY auto_increment ,
    name VARCHAR (
    20),
    gender BIT default
    1,
    birthday DATA ,
    department VARCHAR (
    20),
    salary DECIMAL (
    8,2) unsigned,
    );

    #sql中的表纪录

    #添加一条表纪录:
    INSERT employee (name,gender,birthday,salary,department)
    VALUES (
    "alex",1,"1985-12-12",8000,"保洁部");

    #查询一条表纪录:
    SELECT * FROM employee WHERE age=24;

    #更新一条表纪录:
    UPDATE employee SET birthday="1989-10-24" WHERE id=1;

    #删除一条表纪录:
    DELETE FROM employee WHERE name="alex"

    #python的类
    class Employee(models.Model):
    id
    =models.AutoField(primary_key=True)
    name
    =models.CharField(max_length=32)
    gender
    =models.BooleanField()
    birthday
    =models.DateField()
    department
    =models.CharField(max_length=32)
    salary
    =models.DecimalField(max_digits=8,decimal_places=2)

    #python的类对象
    #添加一条表纪录:
    emp=Employee(name="alex",gender=True,birthday="1985-12-12",epartment="保洁部")
    emp.save()
    #查询一条表纪录:
    Employee.objects.filter(age=24)
    #更新一条表纪录:
    Employee.objects.filter(id=1).update(birthday="1989-10-24")
    #删除一条表纪录:
    Employee.objects.filter(name="alex").delete()

    View Code

    class类的属性和字段是对应的。
    decimal(10,2)表示最大长度为10位。小数点2位。那么整数部分,最大只能有8位。

    ORM的映射关系:

    复制代码
              ORM引擎
    python ---------------> sql
    

    类名 表名
    属性变量 字段
    属性值 约束条件

    对象 一条记录

    复制代码

    比如save(),就可以增加一条记录。所以是对象对应一条记录。

    写项目的注意点:

    写任何一个项目,
    第一件事情,就是产品经理给你提需求。
    最关键的时候,了解产品需求,逻辑关系。判断中途是否有bug!
    如果做不了,一定要直接说,不能藏着。否则后期拖进度,就麻烦了。
    一开始做宏观的梳理,否则后面会出现bug。导致项目推到重构!!!
    对于表的设计,要慎重考虑。
    早期,会经历很多碰壁的过程,这样你就能成长!
    先创建表,分模块来创建表。
    到了写代码的时候,反而是最简单的。
    比如一个商城项目,设计表,梳理流程,花了2个月。写代码,几个星期就完成了。
    View Code

    单表操作

    创建表

    1.  创建模型

    默认在应用文件下,有一个models.py文件,比如app01应用。

    在app01下的models.py中创建模型:

    from django.db import models
    

    # Create your models here.

    class Book(models.Model):
    id
    =models.AutoField(primary_key=True)
    title
    =models.CharField(max_length=32)
    state
    =models.BooleanField()
    pub_date
    =models.DateField()
    price
    =models.DecimalField(max_digits=8,decimal_places=2)
    publish
    =models.CharField(max_length=32)

    View Code

    ORM没法创建数据库,它只能操作表!
    类名,首先字母要大写,它必须继承models.Model。这是固定写法!

    2. 更多字段和参数

    每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。还有一些适用于所有字段的通用参数。 这些参数在文档中有详细定义,这里我们只简单介绍一些最常用的:

    更多字段:

    <1> CharField
            字符串字段, 用于较短的字符串.
            CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所允许的最大字符数.
    

    <2> IntegerField
    #用于保存一个整数.

    <3> FloatField
    一个浮点数. 必须 提供两个参数:

        参数    描述
        max_digits    总位数(不包括小数点和符号)
        decimal_places    小数位数
                举例来说, 要保存最大值为 </span>999<span style="color: #000000;"> (小数点后保存2位),你要这样定义字段:
                 
                models.FloatField(..., max_digits</span>=5, decimal_places=2<span style="color: #000000;">)
                要保存最大值一百万(小数点后保存10位)的话,你要这样定义:
                 
                models.FloatField(..., max_digits</span>=19, decimal_places=10<span style="color: #000000;">)
                admin 用一个文本框(</span>&lt;input type=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span>&gt;<span style="color: #000000;">)表示该字段保存的数据.
    

    <4> AutoField
    一个 IntegerField, 添加记录时它会自动增长. 你通常不需要直接使用这个字段;
    自定义一个主键:my_id
    =models.AutoField(primary_key=True)
    如果你不指定主键的话,系统会自动添加一个主键字段到你的 model.

    <5> BooleanField
    A true
    /false field. admin 用 checkbox 来表示此类字段.

    <6> TextField
    一个容量很大的文本字段.
    admin 用一个
    <textarea> (文本区域)表示该字段数据.(一个多行编辑框).

    <7> EmailField
    一个带有检查Email合法性的 CharField,不接受 maxlength 参数.

    <8> DateField
    一个日期字段. 共有下列额外的可选参数:
    Argument 描述
    auto_now 当对象被保存时,自动将该字段的值设置为当前时间.通常用于表示
    "last-modified" 时间戳.
    auto_now_add 当对象首次被创建时,自动将该字段的值设置为当前时间.通常用于表示对象创建时间.
    (仅仅在admin中有意义...)

    <9> DateTimeField
    一个日期时间字段. 类似 DateField 支持同样的附加选项.

    <10> ImageField
    类似 FileField, 不过要校验上传对象是否是一个合法图片.
    #它有两个可选参数:height_field和width_field,
    如果提供这两个参数,则图片将按提供的高度和宽度规格保存.
    <11> FileField
    一个文件上传字段.
    要求一个必须有的参数: upload_to, 一个用于保存上载文件的本地文件系统路径. 这个路径必须包含 strftime
    #formatting,
    该格式将被上载文件的 date/time
    替换(so that uploaded files don
    't fill up the given directory).
    admin 用一个<input type="file">部件表示该字段保存的数据(一个文件上传部件) .

     注意:在一个 model 中使用 FileField 或 ImageField 需要以下步骤:
            (</span>1<span style="color: #000000;">)在你的 settings 文件中, 定义一个完整路径给 MEDIA_ROOT 以便让 Django在此处保存上传文件.
            (出于性能考虑,这些文件并不保存到数据库.) 定义MEDIA_URL 作为该目录的公共 URL. 要确保该目录对
             WEB服务器用户帐号是可写的.
            (</span>2<span style="color: #000000;">) 在你的 model 中添加 FileField 或 ImageField, 并确保定义了 upload_to 选项,以告诉 Django
             使用 MEDIA_ROOT 的哪个子目录保存上传文件.你的数据库中要保存的只是文件的路径(相对于 MEDIA_ROOT).
             出于习惯你一定很想使用 Django 提供的 get_</span>&lt;<span style="color: #008000;">#</span><span style="color: #008000;">fieldname&gt;_url 函数.举例来说,如果你的 ImageField</span>
             叫作 mug_shot, 你就可以在模板中以 {{ object.<span style="color: #008000;">#</span><span style="color: #008000;">get_mug_shot_url }} 这样的方式得到图像的绝对路径.</span>
    

    <12> URLField
    用于保存 URL. 若 verify_exists 参数为 True (默认), 给定的 URL 会预先检查是否存在( 即URL是否被有效装入且
    没有返回404响应).
    admin 用一个
    <input type="text"> 文本框表示该字段保存的数据(一个单行编辑框)

    <13> NullBooleanField
    类似 BooleanField, 不过允许 NULL 作为其中一个选项. 推荐使用这个字段而不要用 BooleanField 加 null
    =True 选项
    admin 用一个选择框
    <select> (三个可选择的值: "Unknown", "Yes""No" ) 来表示这种字段数据.

    <14> SlugField
    "Slug" 是一个报纸术语. slug 是某个东西的小小标记(短签), 只包含字母,数字,下划线和连字符.#它们通常用于URLs
    若你使用 Django 开发版本,你可以指定 maxlength. 若 maxlength 未指定, Django 会使用默认长度: 50. #
    以前的 Django 版本,没有任何办法改变50 这个长度.
    这暗示了 db_index
    =True.
    它接受一个额外的参数: prepopulate_from, which
    is a list of fields from which to auto-#populate
    the slug, via JavaScript,in the object's admin form: models.SlugField
    (prepopulate_from=("pre_name", "name"))prepopulate_from 不接受 DateTimeFields.

    <13> XMLField
    一个校验值是否为合法XML的 TextField,必须提供参数: schema_path, 它是一个用来校验文本的 RelaxNG schema
    #的文件系统路径.

    <14> FilePathField
    可选项目为某个特定目录下的文件名. 支持三个特殊的参数, 其中第一个是必须提供的.
    参数 描述
    path 必需参数. 一个目录的绝对文件系统路径. FilePathField 据此得到可选项目.
    Example:
    "/home/images".
    match 可选参数. 一个正则表达式, 作为一个字符串, FilePathField 将使用它过滤文件名.
    注意这个正则表达式只会应用到 base filename 而不是
    路径全名. Example:
    "foo..txt^", 将匹配文件 foo23.txt 却不匹配 bar.txt 或 foo23.gif.
    recursive可选参数.要么 True 要么 False. 默认值是 False. 是否包括 path 下面的全部子目录.
    这三个参数可以同时使用.
    match 仅应用于 base filename, 而不是路径全名. 那么,这个例子:
    FilePathField(path
    ="/home/images", match="foo.
    ", recursive=True)
    ...会匹配
    /home/images/foo.gif 而不匹配 /home/images/foo/bar.gif

    <15> IPAddressField
    一个字符串形式的 IP 地址, (i.e.
    "24.124.1.30").
    <16> CommaSeparatedIntegerField
    用于存放逗号分隔的整数值. 类似 CharField, 必须要有maxlength参数.

    View Code

    更多参数:

    (1)null
    

    如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.

    (1)blank

    如果为True,该字段允许不填。默认为False。
    要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
    如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。

    (2)default

    字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。

    (3)primary_key

    如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,
    Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
    否则没必要设置任何一个字段的primary_key
    =True。

    (4)unique

    如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的

    (5)choices
    由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,
    <br>而且这个选择框的选项就是choices 中的选项。

    View Code

    3. settings配置

    首先是注册app:
    修改mysite下的settings.py文件里面的INSTALLED_APPS。注册你的app,最后一行添加,我用的app名是app01

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',
    ]
    View Code

    不注册它,你的数据库就不知道该给哪个app创建表。

    若想将模型转为mysql数据库中的表,需要在settings中配置:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',   # 数据库引擎mysql
            'NAME': 'book',       # 你要存储数据的库名,事先要创建之
            'USER': 'root',      # 数据库用户名
            'PASSWORD': '',      # 密码
            'HOST': 'localhost', # 主机
            'PORT': '3306',      # 数据库使用的端口
        }
    }
    View Code

    注意1:NAME即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建 USER和PASSWORD分别是数据库的用户名和密码。

    由于ORM不能创建数据库,需要手动创建。

    进入mysql,创建数据库book。

    C:Usersxiao>mysql -u root
    Welcome to the MySQL monitor.  Commands end with ; or g.
    Your MySQL connection id is 9
    Server version: 5.7.22-log MySQL Community Server (GPL)
    

    Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.

    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

    mysql> CREATE DATABASE book DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
    Query OK,
    1 row affected (0.01 sec)

    mysql>

    View Code

    django连接MySQL,使用的是pymysql模块,必须得安装2个模块。否则后面会创建表不成功!或者提示no module named MySQLdb 

    pip3 install pymysql
    pip3 install mysqlclient

    注意:某些windows电脑安装 mysqlclient会提示C++缺失。

    启动项目,会报错:no module named MySQLdb 。这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb 对于py3有很大问题,所以我们需要的驱动是PyMySQL

    所以,我们只需要找到app01(应用名)文件下的__init__,在里面写入:

    import pymysql
    pymysql.install_as_MySQLdb()

    接下来要在pycharm的teminal中通过命令创建数据库的表了。有2条命令,分别是:

    python manage.py makemigrations

    E:python_scriptdjango框架day5mysite>python manage.py makemigrations
    Migrations for 'app01':
      app01migrations001_initial.py
        - Create model Book
    View Code

    它的作用相当于 在该app下建立 migrations目录,并记录下你所有的关于modes.py的改动,比如0001_initial.py, 但是这个改动还没有作用到数据库文件

    再输入命令:

    python manage.py migrate

    E:python_scriptdjango框架day5mysite>python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, app01, auth, contenttypes, sessions
    Running migrations:
      Applying contenttypes.0001_initial... OK
      Applying auth.0001_initial... OK
      Applying admin.0001_initial... OK
      Applying admin.0002_logentry_remove_auto_add... OK
      Applying app01.0001_initial... OK
      Applying contenttypes.0002_remove_content_type_name... OK
      Applying auth.0002_alter_permission_name_max_length... OK
      Applying auth.0003_alter_user_email_max_length... OK
      Applying auth.0004_alter_user_username_opts... OK
      Applying auth.0005_alter_user_last_login_null... OK
      Applying auth.0006_require_contenttypes_0002... OK
      Applying auth.0007_alter_validators_add_error_messages... OK
      Applying auth.0008_alter_user_username_max_length... OK
      Applying auth.0009_alter_user_last_name_max_length... OK
      Applying sessions.0001_initial... OK
    View Code

    它是将该改动作用到数据库文件,比如创建表,修改表字段之类的操作。

    注意2: 如果想打印orm转换过程中的sql,需要在settings中进行如下配置:

    最后一行添加即可!

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console':{
                'level':'DEBUG',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level':'DEBUG',
            },
        }
    }
    View Code

     演示一下:

    删除数据库book

    mysql> drop database book;
    Query OK, 11 rows affected (1.95 sec)
    

    mysql> CREATE DATABASE book DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
    Query OK,
    1 row affected (0.00 sec)

    View Code

    删除app01目录下的migrations文件夹

     重新执行上面2个命令

    python manage.py makemigrations

    E:python_scriptdjango框架day5mysite>python manage.py makemigrations
    (0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
    (0.000) SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; args=None
    (0.001) SELECT VERSION(); args=None
    (0.000) SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; args=None
    (0.001) SHOW FULL TABLES; args=None
    No changes detected
    View Code

    python manage.py migrate

    E:python_scriptdjango框架day5mysite>python manage.py migrate
    (0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
    (0.000) SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; args=None
    (0.000) SELECT @@sql_mode; args=None
    (0.001) SELECT VERSION(); args=None
    (0.001) SHOW FULL TABLES; args=None
    (0.000) SHOW FULL TABLES; args=None
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, sessions
    Running migrations:
    (0.001) SHOW FULL TABLES; args=None
    CREATE TABLE `django_migrations` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `app` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `applied` datetime(6) NOT NULL); (params None)
    (0.252) CREATE TABLE `django_migrations` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `app` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `applied` datetime(6) NOT NULL); args=None
    ...
    View Code

    上面这个命令输出内容太多了,直接...代替了!

     
     

    参考资料:

    Django 基础教程

    转载声明:
    作者:肖祥
    出处: https://www.cnblogs.com/xiao987334176/

  • 相关阅读:
    Elasticsearch本地环境安装和常用操作
    Scala快速入门
    Flink本地安装和创建Flink应用
    Elasticsearch源码分析
    android6,0申请权限
    JDK动态代理
    Navicat 连接MySQL8.0,错误:Authentication plugin 'caching_sha2_password' cannot be loaded
    mysqldump
    mysql配置远程登录
    将博客搬至CSDN
  • 原文地址:https://www.cnblogs.com/bqwzx/p/10160014.html
Copyright © 2020-2023  润新知