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

昨日内容回顾

复制代码
视图函数:

    request对象
         request.path  请求路径
         request.GET   GET请求数据  QueryDict  {}
         request.POST  POST请求数据 QueryDict  {}
         request.method 请求方式    "GET"   "POST"
         request.is_ajax()       是否是Ajax请求
         request.get_full_path()    包含请求数据的路径
         
    return HttpResponse("响应体字符串")
    
    render  :渲染
        render(request,"index.html")
        render(request,"index.html",{"name":name})
    
    redirect: 重定向
        两次请求
复制代码

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/')

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

分析一下:

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第1张图片

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

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

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第2张图片

模板

模板:
    
    一 变量 {{}}
       1 深度查询   .
       2 过滤器
         {{now|date:"Y-m-d"}}
         {{file_size:filesizeformat}} 
         {{link|safe}}

    二 标签{% %}        
        1.
        {% for i in []%}
        {{forloop.counter}}
        {{forloop.last}}
        {%endfor%}
        2.
        {% if  条件%}
        

1111

{%elif%}

2222

{%else%}

3333

{%endif%} 3 with 4 url {% url '别名' 参数 %} 5 {% csrf_token %}
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 %}

{{ num|multi_filter:5 }}

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 %}

{{ num_list|multi_filter }}

View Code

访问网页,输出:

 

举例1:显示a标签

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

@register.filter
def link_tag(href):
    return "click"%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 %}

{{ link|link_tag }}

View Code

访问网页,输出:

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

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第3张图片

因为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("click" % 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 %}

{% multi_tag 7 8 9 %}

View Code

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

 

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

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

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

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

 

二、模板继承 (extend)

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

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

include

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


"en">

    "UTF-8">
    Title
    "stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">



class="row">
class="col-md-4">
class="advertise">
class="panel panel-danger">
class="panel-heading">菜单一
class="panel-body"> Panel content
class="panel panel-success">
class="panel-heading">菜单一
class="panel-body"> Panel content
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/

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第4张图片

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

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

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

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

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


"en">

    "UTF-8">
    Title
    "stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">


{% include 'advertise.html' %}

View Code

访问首页,效果同上。

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第5张图片

 

 extend

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

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

举例:图书网页

编辑index.html


"en">

    "UTF-8">
    Title
    "stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
    


class="header">

class="title"> 路飞学诚

class="container">
class="row">
class="col-md-3">
class="panel panel-danger">
class="panel-heading">菜单一
class="panel-body"> Panel content
class="panel panel-success">
class="panel-heading">菜单二
class="panel-body"> Panel content
class="panel panel-warning">
class="panel-heading">菜单三
class="panel-body"> Panel content
class="col-md-9">
View Code

访问index页面,输出:

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第6张图片

 

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

修改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的代码全部复制粘贴过来,修改中间内容


"en">

    "UTF-8">
    Title
    "stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
    


class="header">

class="title"> 路飞学诚

class="container">
class="row">
class="col-md-3">
class="panel panel-danger">
class="panel-heading">菜单一
class="panel-body"> Panel content
class="panel panel-success">
class="panel-heading">菜单二
class="panel-body"> Panel content
class="panel panel-warning">
class="panel-heading">菜单三
class="panel-body"> Panel content
class="col-md-9">
class="article_list">
  • 红楼梦
  • 三国演义
  • 西游记
  • 水浒传
View Code

访问articles页面,效果如下:

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第7张图片

 

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


"en">

    "UTF-8">
    Title
    "stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
    


class="header">

class="title"> 路飞学诚

class="container">
class="row">
class="col-md-3">
class="panel panel-danger">
class="panel-heading">菜单一
class="panel-body"> Panel content
class="panel panel-success">
class="panel-heading">菜单二
class="panel-body"> Panel content
class="panel panel-warning">
class="panel-heading">菜单三
class="panel-body"> Panel content
class="col-md-9">
class="author_list">
  • 曹雪芹
  • 罗贯中
  • 吴承恩
  • 施耐庵
View Code

访问authors页面,效果如下:

 python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第8张图片

 

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

 

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

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

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


"en">

    "UTF-8">
     title
    "stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    



class="header">

class="title"> 路飞学诚

class="container">
class="row">
class="col-md-3">
class="panel panel-danger">
class="panel-body"> Panel content
class="panel panel-success">
class="panel-body"> Panel content
class="panel panel-warning">
class="panel-body"> Panel content
class="col-md-9"> {% block content %} {% endblock %}
View Code

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

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

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

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

{% extends 'base.html' %}

{% block content %}

{% endblock %}
View Code

访问index页面,效果如下:

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第9张图片

 

修改articles.html,继承base.html

{% extends 'base.html' %}

{% block content %}
class="article_list">
  • 红楼梦
  • 三国演义
  • 西游记
  • 水浒传
{% endblock %}
View Code

访问articles页面,效果如下:

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第10张图片

修改authors.html,继承base.html

{% extends 'base.html' %}

{% block content %}
class="author_list">
  • 曹雪芹
  • 罗贯中
  • 吴承恩
  • 施耐庵
{% endblock %}
View Code

访问authors页面,效果如下:

 python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第11张图片

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

 

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

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

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


"en">

    "UTF-8">
    {% block title %}
     title
    {% endblock title %}
    
    "stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    



class="header">

class="title"> 路飞学诚

class="container">
class="row">
class="col-md-3">
class="panel panel-danger">
class="panel-body"> Panel content
class="panel panel-success">
class="panel-body"> Panel content
class="panel panel-warning">
class="panel-body"> Panel content
class="col-md-9"> {% block content %} {% endblock %}
View Code

修改articles.html,增加一个block

{% extends 'base.html' %}

{% block content %}
 {{ block.super }}
 
class="article_list">
  • 红楼梦
  • 三国演义
  • 西游记
  • 水浒传
{% endblock %} {% block title %} Article {% endblock %}
View Code

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

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第12张图片

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

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

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第13张图片

 

现在有一个问题,右侧内容,写死了。比如文章页中的内容
修改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 %}
 
class="article_list">
    {% for article in acticle_list %}
  • {{ article }}
  • {% endfor %}
{% endblock %} {% block title %} Article {% endblock %}
View Code

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

{% extends 'base.html' %}

{% block content %}
class="author_list">
    {% for author in author_list %}
  • {{ author }}
  • {% endfor %}
{% endblock %} {% block title %} Author {% endblock %}
View Code

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

 

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

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

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

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

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

{% block content %}

{% endblock %}

{% extends 'base.html' %}
View Code

 访问网页,就会报错

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第14张图片

 

  • 在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 %}

详细内容

{% endblock %}

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

{% extends 'base.html' %}

{% block content %}
{{ block.super }}
 
class="article_list">
    {% for article in acticle_list %}
  • {{ article }}
  • {% endfor %}
{% endblock %} {% block title %} Article {% endblock %}
View Code

访问articles页面,效果如下

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第15张图片

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

 

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

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

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

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

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

 

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

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


"en">

    "UTF-8">
    {% block title %}
     title
    {% endblock title %}

    "stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    



class="header">

class="title"> 路飞学诚

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

详细内容

{% endblock %}
View Code

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

效果如下:

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第16张图片

 

 

三、Django的模型层-ORM简介

ORM简介

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

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

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

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

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

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

看下图:

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第17张图片

 

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是“对象-关系-映射”的简称。

python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)..._第18张图片

上图有一个错误,类型是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    小数位数
                举例来说, 要保存最大值为 999 (小数点后保存2位),你要这样定义字段:
                 
                models.FloatField(..., max_digits=5, decimal_places=2)
                要保存最大值一百万(小数点后保存10位)的话,你要这样定义:
                 
                models.FloatField(..., max_digits=19, decimal_places=10)
                admin 用一个文本框("text">)表示该字段保存的数据.
 
<4> AutoField
        一个 IntegerField, 添加记录时它会自动增长. 你通常不需要直接使用这个字段;
        自定义一个主键:my_id=models.AutoField(primary_key=True)
        如果你不指定主键的话,系统会自动添加一个主键字段到你的 model.
 
<5> BooleanField
        A true/false field. admin 用 checkbox 来表示此类字段.
 
<6> TextField
        一个容量很大的文本字段.
        admin 用一个