python Django

Python Django install

  1. python virtualenv

    1
    2
    3
    4
    [root@dev ~]# pyenv virtualenv 2.7.13 cmdb
    [root@dev ~]# pyenv virtualenvs
    [root@dev ~]# pyenv activate cmdb
    (cmdb) [root@dev ~]# source deactivate
    1
    2
    3
    [root@dev ~]# pyenv install 3.6.1
    [root@dev ~]# pyenv virtualenv 3.6.1 oeaoo
    [root@dev ~]# pyenv activate oeaoo
  2. django install

    1
    2
    3
    4
    5
    6
    7
    8
    [root@dev ~]# pyenv activate cmdb
    (cmdb) [root@dev ~]# pip install django==1.11.1

    (cmdb) [root@dev ~]# python
    Python 2.7.13 (default, May 22 2017, 11:51:24)
    >>> import django
    >>> print(django.VERSION)
    (1, 11, 1, u'final', 0)
    1
    2
    3
    4
    5
    (oeaoo) [root@dev web]# pip install django==1.11.2
    (oeaoo) [root@dev web]# python
    >>> import django
    >>> print(django.get_version())
    1.11.2

Python Django 开发站点

  1. 建立项目

    1
    2
    3
    4
    5
    6
    7
    8
    9
    (cmdb) [root@dev ~]# django-admin startproject djangosite
    (cmdb) [root@dev ~]# tree djangosite/
    djangosite/
    ├── djangosite
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    (oeaoo) [root@dev oeaoo]# django-admin startproject cmdb
    (oeaoo) [root@dev oeaoo]# tree cmdb/
    cmdb/
    ├── cmdb
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py
  2. 建立应用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    (cmdb) [root@dev ~]# cd djangosite/
    (cmdb) [root@dev djangosite]# python manage.py startapp app
    (cmdb) [root@dev djangosite]# tree .
    .
    ├── app
    │   ├── admin.py
    │   ├── apps.py
    │   ├── __init__.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── djangosite
    │   ├── __init__.py
    │   ├── __init__.pyc
    │   ├── settings.py
    │   ├── settings.pyc
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    (oeaoo) [root@dev cmdb]# python manage.py startapp polls
    (oeaoo) [root@dev cmdb]# tree .
    .
    ├── cmdb
    │   ├── __init__.py
    │   ├── __pycache__
    │   │   ├── __init__.cpython-36.pyc
    │   │   ├── settings.cpython-36.pyc
    │   │   ├── urls.cpython-36.pyc
    │   │   └── wsgi.cpython-36.pyc
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── db.sqlite3
    ├── manage.py
    └── polls
    ├── admin.py
    ├── apps.py
    ├── __init__.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py
  3. 基本视图

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    * 建立路由响应函数
    (cmdb) [root@dev djangosite]# vim app/views.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.shortcuts import render
    # Create your views here.
    from django.http import HttpResponse
    def welecome(request):
    return HttpResponse("<h1>Welecome to my website!</h1>")

    * 通过URL映射将用户的HTTP访问与该函数绑定起来
    (cmdb) [root@dev djangosite]# vim app/urls.py
    from django.conf.urls import url
    from . import views
    urlpatterns = [
    url(r'',views.welecome)
    ]

    * 在项目URL文件中的urlpatterns参数中增加一项,声明对应用app中的ruls.py文件的引用
    (cmdb) [root@dev djangosite]# vim djangosite/urls.py
    from django.conf.urls import url
    from django.contrib import admin
    from django.conf.urls import include #新增
    urlpatterns = [
    url(r'^app/', include('app.urls')), #新增
    url(r'^admin/', admin.site.urls),
    ]
  4. 内置web服务器

    1
    2
    3
    4
    5
    (cmdb) [root@dev djangosite]# pwd
    /root/djangosite
    (cmdb) [root@dev djangosite]# python manage.py runserver 0.0.0.0:8080

    浏览器中输入: http://127.0.0.1:8080/app/ 进行检查
  5. 摸类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    * 配置项目INSTALLED_APPS
    要在djangosite项目的setting.py中告诉Django需要安装应用app中的模型,则方法是找到djangosite/setting.py文件,找到INSTALLED_APPS数组,在其中添加应用app的Config类
    (cmdb) [root@dev djangosite]# pwd
    /root/djangosite
    (cmdb) [root@dev djangosite]# vim djangosite/settings.py
    INSTALLED_APPS = [
    'app.apps.AppConfig', #新增
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    ]
    注意: 上面声明的是djangosite/app/apps.py中自动生成的AppConfig类

    * 模型定义
    定义一个模型类Moment用来定义信息发布表
    (cmdb) [root@dev djangosite]# vim app/models.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.db import models #所有的模型类必须继承自它
    # Create your models here.
    class Monment(models.Model): #定义了models.Model的子类Monment
    content = models.CharField(max_length=200)
    user_name = models.CharField(max_length=20)
    kind = models.CharField(max_length=20)

    * 生成数据移植文件
    生成数据移植文件是指将models.py中定义的数据表转换成数据库生成脚本的过程
    (cmdb) [root@dev djangosite]# pwd
    /root/djangosite
    (cmdb) [root@dev djangosite]# python manage.py makemigrations app
    Migrations for 'app':
    app/migrations/0001_initial.py
    - Create model Monment

    * 将数据移植文件应用到数据库
    (cmdb) [root@dev djangosite]# pwd
    /root/djangosite
    (cmdb) [root@dev djangosite]# python manage.py migrate
    Operations to perform:
    Apply all migrations: admin, app, auth, contenttypes, sessions
    Running migrations:
    Applying app.0001_initial... OK
    Applying app.0002_auto_20170523_0338... OK
    在命令执行过程中将检查djangosite/app/migrations目录中的所有文件,逐步使历次生成的移植文件生效
  6. 表单视图

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    设计和开发信息录入页面:提供输入界面,让用户输入名字,文本信息内容和选择消息类型.用户提交后网页自动设置该信息的时间并保持到数据库中

    * 定义表单类
    (cmdb) [root@dev djangosite]# pwd
    /root/djangosite
    (cmdb) [root@dev djangosite]# vim app/forms.py
    # -*- coding: utf-8 -*-
    from django.forms import ModelForm #引入django表单类的基类
    from app.models import Moment #引入models定义的Moment类,以便后面表单中关联Moment类

    class MomentForm(ModelForm): #定义表单类MomentForm类,继承ModelForm.
    class Meta: #定义子类Meta,声明与本表单关联的模型类及其字段
    model = Moment
    fields = '__all__'

    * 修改模型类
    为了使用户能以单选的方式设置消息类型,则需要在models.py文件中定义单选枚举值,并与模型类Moment关联
    (cmdb) [root@dev djangosite]# vim app/models.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.db import models
    # 声明元组用于设置消息类型枚举项
    KIND_CHOICES = (
    ('python技术','python技术'),
    ('数据库技术','据库技术'),
    ('个人中心','个人中心'),
    ('其它','其它'),
    )
    # Create your models here.
    class Monment(models.Model):
    content = models.CharField(max_length=300)
    user_name = models.CharField(max_length=20,default='匿名')
    kind = models.CharField(max_length=20,choices=KIND_CHOICES,default=KIND_CHOICES[0])

    * 开发模板文件
    模板是python web框架中用于产生HTML,XML等文本格式文档的术语
    模板文件本身也是一种文本文件,开发者需要手工对齐编辑开发
    //创建模板存放目录
    (cmdb) [root@dev djangosite]# mkdir app/templates
    //创建模板文件
    (cmdb) [root@dev djangosite]# vim app/templates/moments_input.html
    <!DOCTPYPE html>
    <html>
    <head>
    <title>消息录入界面</title>
    </head>
    <body>
    <form action="?" method="post">
    <fieldset>
    <legend>请输入并提交</legend>
    {{form.as_p}}
    <input type="submit" value="submit" />
    </fieldset>
    </form>
    </body>
    </html>

    * 开发视图(使得表单类和页面模板衔接起来)
    (cmdb) [root@dev djangosite]# vim app/views.py
    # -*- coding: utf-8 -*-
    import os
    from __future__ import unicode_literals
    from app.forms import MomentForm
    from django.shortcuts import render
    from django.http import HttpResponse
    from django.core.urlresolvers import reverse
    def welcome(request):
    return HttpResponse("<h1>Welecome to my website!</h1>")
    def monments_input(request):
    if request.method == 'POST':
    form = MomentFrom(request.POST)
    if form.is_valid():
    moment = form.save()
    moment.save()
    return HttpResponseRedirect(reverse("app.views.welcome"))
    else:
    form = MomentFrom()
    PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    return render(request,os.path.join(PROJECT_ROOT,'app/templates','moments_input.html',{'form': form}))

    * 增加视图函数路由映射
    (cmdb) [root@dev djangosite]# vim app/urls.py
    from django.conf.urls import url
    from . import views
    urlpatterns = [
    url(r'moments_input',views.moments_input,name='moments_input'),
    url(r'',views.welcome,name='welcome'),
    ]
  7. Django模型层

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    Django模型层是Django框架自定义的一套独特的ORM技术.

    使用Django模型开发的首要任务是定义模型类及其属性.每个模型类都可以被映射为数据库中的一个数据表,而类型属性被定义为数据字段,除此之外,数据库表的主键,外键,约束也通过类的属性完成定义

    * 模型类定义
    from django.db import models

    class ModelName(models.Model):
    field1 = models.XXField(...)
    field2 = models.XXField(...)

    class Meta:
    db_table = ...
    other_metas = ...

    解析:
    * 所有的Django模型继承自django.db.models.Model类
    * 通过其中的类属性定义模型字段,模型字段必须是某种models.XXField类型
    * 通过模型类中的Meta子类定义模型元数据,比如数据库表名,数据默认排序等

    Meta类的属性名由Django预定于,通用属性如下:
    * abstract True/False,标识是否为抽象基类
    * app_label 定义本类所属的应用,例如: app_label="myapp"
    * db_table 映射的数据表名(如果未定义,则默认生成数据表,表名为"应用名_模型名")
    * db_tablespace 映射表空间名(表空间在oracle和postgresql中存在)
    * default_related_name 定义模型的反向关系引用名称,默认与模型名一样
    * get_latest_by 定义按哪个字段值排列以获得模型开始或结束记录,本属性值通常指向一个日期或整型的模型字段
    * managed True/False,定义Django的manage.py命令行工具是否管理本模型
    * order_with_respect_to 定义模型可以按照某外键引用关系排序
    * ordering 本模型记录的默认排序字段,可以设置多个字段,默认以升序排序,降序需要在前面加负号(-)
    * default_permissions 模型操作权限(add,change,delete)
    * proxy True/False,本模型及所有继承自本模型的子模型是否为代理模型
    * require_db_features 定义底层数据库所必须具备的特性
    * require_db_vendor 定义底层数据库类型(SQLite,PostgreSQL,MySQL,Oracle)
    * unique_together 用来设置不重复的字段组合,必须唯一
    * index_together 定义联合索引的字段,可以设置多个
    * verbose_name 指明一个易于理解和表述的单数形式的对象名称
    * verbose_name_plural 指明一个易于理解和表述的复数形式对象名称

    * 普通字段类型
    普通字段类型中除外键关系外的数据字段属性.
    所有的字段属性必须继承自抽象类django.db.models.Field,开发可以自定义继承自该类的字段类型

    预定于类型:
    * AutoField 一个自动递增的整形字段,添加记录时会自动增长(充当主键)
    * BigIntegerField 64位整型字段
    * BinaryField 二进制数据字段,只能通过bytes对其进行赋值
    * BooleanField 布尔字段,对应html标签"<input type="checkbox">"
    * CharField 字符串字段,用于较短的字符串,对应于html标签"<input type="text">"
    * TextField 大容量字段,对应于html标签是多行编辑框"<textarea>"
    * CommaSeparatedIntegerField 用于存放逗号分隔的整数值
    * DateField 日期字段,对应于html标签是"<input type="text">"
    * DateTimeField 类似于DateField,但同时支持于时间的输入
    * DurationField 存储时间周期
    * EmailField 一个带有检查Email合法性的CharField
    * FileField 一个文件上传字段
    * FilePathField 按目录限制规则选择文件,定义本字段时必须传入参数path,用于限定目录
    * FloatField 浮点型字段
    * ImageField 类似FileField,同时校验上传对象是否是一个合法图片
    * IntegerField 用于保存一个整数
    * IPAddressField 一个字符串形式的IP地址
    * NullBooleanField 类似BooleanField,但多出一个None选项
    * PhoneNumberField 带有美国风格的电话号码校验(xxx-xxx-xxxx)
    * PositiveIntegerField 只能输入非负数的IntegerField
    * SlugField 只包含字母,数字,下划线和连字符输入字段,用于URL
    * SmallIntegerField 类似IntegerField,但只有较小的输入范围
    * TimeField 时间字段,但只能表达和输入时间
    * URLField 用于保存URL
    * USStateField 美国州名缩小,由两个字段组成
    * XMLField XML字符字段

    * 字段类型参数
    每个字段类型都有一些特定的HTML标签和表单验证参数.但同时也有一些每个字段都可以设置的公共参数
    公共参数:
    * null 定义是否允许相对应的数据库字段为null,默认为False
    * blank 定义字段是否可以为空.blank用于字段HTML表单验证.null用于数据库中的非空约束
    * choices 定义字段可选值
    * default 定义默认值
    * help_text HTML页面中输入控件的帮助信息
    * primary_key 定义字段是否为主键
    * unique 定义字段数据是否是唯一
    * 无名参数,人性化设置

    * 基本查询
    Django有两种过滤器用于筛选数据:
    * filter(**kwargs) 返回符合筛选条件的数据集
    * exclude(**kwargs) 返回不符合筛选条件的数据集
    * 多个filter和exclude可以组合在一起使用

    * 数据保存和删除
    Django定义了一个统一的方法"save()",用于完成模型的Insert和update操作
    在执行模型实例Save()时,Django会根据模型的主键,判断记录是否存在,存在则Update操作,不存在则Insert操作

    Django提供了delete()方法用于删除记录,该方法即可以用于数据集,又可以用于单条记录

    * 关系操作
    利用数据表之间的关系进行数据建模和业务开发是关系数据库最主要的功能

    //一对一关系
    一对一关系通过在两个表之间定义相同的主键来完成(OneToOneField)
    //一堆多关系
    一对多关系通过"附表"中设置到"主表"的外键引用来完成(models.ForeignKey定义外键)
    //多对多关系
    多对多关系通过建立一个中间关系表来完成,该中间表定义了到两个主表的外键

    * 面向对象ORM
    Django支持三种风格的模型继承:
    * 抽象类继承
    父类继承自models.Model,但不会在底层数据库中生成相应的数据表.父类的属性列存储在其子类的数据表中
    * 多表继承
    多表继承的每个模型类都在底层数据库中生成相应的数据表管理数据
    * 代理模型继承
    父类用于在底层数据库中管理数据表,而子类不顶用数据列,只定义查询数据集的排序方式等元数据