Django

一、Django简介

  第一个开放源代码的WEB应用框架,由python写成,初次发布于2005年7月,并于2008年9月发布了第一个正式版本1.0。主要有两种模式:MVC和MTV

  MVC:

    概述:一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进 和个性化定制界面及用户交互的同时,不需

                         要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理 和输出功能在一个逻辑的图形化用户界面的结构中

    核心思想:解耦

    图解:

      

    编程模式:

      Model(模式)

        是应用程序中用于处理应用程序数据逻辑的部分

        通常模型对象负责在数据库中存取数据

      View(视图)

        是应用程序中处理数据显示的部分

        通常视图是依据模型数据创建的

      Controller(控制器)

        是应用程序中处理用户交互的部分

        通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据

    优点:

      降低各功能模块之间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的复用

  MTV:

    概述:本质上与MVC模式没有什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同

    编程模式:

      Model(模型):负责业务对象与数据库的对象(ORM)

      Template(模版):负责如何把页面展示给用户

      View(视图):负责业务逻辑,并在适当的时候调用Model和Template

    注意:Django还有一个url分发器,它的作用是将一个个URL的页面请求 分发给不同的view处理,view再调用相应的Model和Template

二、Django创建项目

  在合适位置创建一个文件夹

  打开黑屏终端进入到上一步创建的文件夹目录下

  输入命令:django-admin  startproject  project

  目录层级说明:

    manage.py:一个命令行工具,可以使我们用多种方式对Django项目进行交互

    project目录:

      __init__.py:一个空文件,它告诉python这个目录应该被看作一个python包

      settings.py:项目的配置文件

      urls.py:项目的URL声明

      wsgi.py:项目与WSGI兼容的Web服务器入口

三、Django基本操作

  1、设计表结构:这个不同的项目设计的表结构不同,这里不详细说

  2、配置数据库

    启动数据库:net  start  mysql

    注意:Django默认使用的是SQLite数据库

    在settings.py文件中,通过DATABASES选项进行数据库配置

    配置MySQL:

      python3.x安装的是PyMySQL

      在__init__.py文件中写入两行代码 

        
1 import pymysql
2 pymysql.install_as_MySQLdb()
View Code

      格式    

        
1 DATABASES = {
2     'default': {        'ENGINE''django.db.backends.mysql',
3                             'NAME': "数据库名",     
4                             'USER': '用户名',
5                             'PASSWORD': '数据库密码',
6                             'HOST': '数据库服务器IP',
7                             'PORT': '端口',
8     }
9 }                
View Code

  3、创建应用

    在一个项目中可以创建多个应用,每个应用进行一种业务处理

    打开黑屏终端进入上次创建文件夹下的project目录

    执行命令:python  manage.py  startapp myApp

    myApp目录说明:

      admin.py:站点配置

      models.py:模型

      views.py:视图

  4、激活应用

    在settings.py文件中,将myApp应用加入到INSTALLED_APPS选项中 

      
1 INSTALLED_APPS = [
2     'django.contrib.admin',
3     'django.contrib.auth',
4     'django.contrib.contenttypes',
5     'django.contrib.sessions',
6     'django.contrib.messages',
7     'django.contrib.staticfiles',
8     'myApp',
9 ]
View Code

  5、定义模型

    概述:有一个数据表,就对应有一个模型

    在models.py文件中定义模型

      引入from django.db  import  models

      模型类要继承models.Model类,代码如下

        
 1 from django.db import models
 2 
 3 # Create your models here.
 4 
 5 class Grades(models.Model):
 6     # 定义模型类
 7     gname = models.CharField(max_length=20)
 8     gdate = models.DateTimeField()
 9     ggirlnum = models.IntegerField()
10     gboynum = models.IntegerField()
11     isDelete = models.BooleanField(default=False)
12     
13 class Students(models.Model):
14     sname = models.CharField(max_length=20)
15     sgender = models.BooleanField(default=True)
16     sage = models.IntegerField()
17     scontend = models.CharField(max_length=20)
18     isDelete = models.BooleanField(default=False)
19     # 关联外键
20     sgrade = models.ForeignKey('Grades')
View Code

    说明:不需要定义主键,在生成时自动添加,并且值为自动增加

  6、在数据库中生成数据表

     生成迁移文件: 

        执行命令:python  manage.py  makemigrations

        在migrations目录下生成一个迁移文件,此时,数据库中还没有生成数据表

     执行迁移:

        执行命令:python  manage.py  migrate  相当于执行SQL语句创建数据表

  7、测试数据操作

    进入到python  shell:

      执行命令:python  manage.py shell

    引入包: 

      1 from  myApp.models  import Grades,Students                          
      2 from datetime import *                                                  
      3 from django.utils import timezone

    查询所有数据:

      语法:类名.objects.all()

      示例:Grades.objects.all()

    添加数据:

      本质:创建一个模型类的对象实例

       
1 >>> grade1 = Grades()
2 >>> grade1.gname = "python04"
3 >>> grade1.gdate = datetime(year=2017,month=7,day=17)
4 >>> grade1.ggirlnum = 3
5 >>> grade1.gboynum = 70
6 >>> grade1.save()
View Code

    查看某个对象:

      语法:类名.objects.get(pk=2)

      示例:Grades.objects.get(pk=2)

    修改数据:

      语法:模型对象.属性 = 新值

      示例: 1 >>> grade2.gboynum = 60      2 >>> grade2.save() 

    删除数据:

      语法:模型对象.delete()

      示例:grade2.delete()

      注意:物理删除,数据库中的表里面的数据永久被删除

    关联对象:

       
1 >>> grade1 = Grades.objects.get(pk=1)
2 >>> stu = Students()
3 >>> stu.sname = "薛艳梅"
4 >>> stu.sgender = False
5 >>> stu.sage = 20
6 >>> stu.scontend = "我叫薛艳梅"
7 >>> stu.sgrade = grade1
8 >>> stu.save()
View Code

      获得关联对象的集合:

        需求:获取python04班级的学生

        语法:对象名.关联的类名小写_set.all()

        示例:grade1.students_set.all()

      创建关联对象:

        stu3 = grade1.students_set.create(sname="曾志伟",sgender=True,scontend="我叫曾志伟",sage=45)

        注意:直接添加到数据库中

  8、启动服务器

    格式:python  manage.py  runserver  ip:port

      ip可以不写,不写的话代表本机ip

      端口号默认是8000

    说明: 这是一个纯python写的轻量级web服务器,仅仅在开发测试中使用

  9、Admin站点管理

    概述:内容发布(负责添加、修改删除内容)、公告访问

    配置admin应用:

      在settings.py文件中的INSTALLED_APPS中添加'django.contrib.admin',

      默认是已经添加的

    创建管理员用户:

      执行命令:python  manage.py  createsuperuser

      依次输入用户名、邮箱、密码

    汉化:

      修改settings.py文件

        LANGUAGE_CODE = 'zh-Hans'

        TIME_ZONE = 'Asia/Shanghai'

    管理数据表:

      修改admin.py文件

         
1 from .models import Grades,Students
2 admin.site.register(Grades)
3 admin.site.register(Students)
View Code

      自定义管理页面    

         
 1 from .models import Grades,Students
 2 # 注册
 3 class GradesAdmin(admin.ModelAdmin):
 4     # 列表页属性
 5     list_display = ['pk', 'gname', 'gdate', 'ggirlnum', 'gboynum', 'isDelete']
 6     list_filter = ['gname',]
 7     search_fields = ['gname']
 8     list_per_page = 5
 9     # 添加、修改页属性
10     # fields = ['ggirlnum', 'gboynum', 'gname', 'gdate', 'isDelete']
11     fieldsets = [
12         ('num', {'fields':['ggirlnum', 'gboynum']}),
13         ('base', {'fields':['gname', 'gdate', 'isDelete']})
14     ]
15 admin.site.register(Grades, GradesAdmin)
View Code

      属性说明

        列表页属性   

            
1 list_display        显示字段
2 list_filter           过滤字段
3 search_fields     搜索字段
4 list_per_page    分页
View Code

        添加、修改页属性

            
1 fields        规定属性的先后顺序
2 fieldsets    给属性分组
3 注意:fields与fieldsets不能同时使用
View Code

      关联对象

        需求:在创建一个班级时可以直接添加几个学生 

         
1 class StudentsInfo(admin.TabularInline):  # StackedInline
2     model = Students
3     extra = 2
4 class GradesAdmin(admin.ModelAdmin):
5     inlines = [StudentsInfo]
View Code

      布尔值显示问题  

         
 1 class StudentsAdmin(admin.ModelAdmin):
 2     def gender(self):
 3         if self.sgender:
 4             return ''
 5         else:
 6             return ''
 7     # 设置页面列的名称
 8     gender.short_description = "性别"
 9     list_display = ['pk', 'sname', 'sage', gender, 'scontend', 'sgrade', 'isDelete']
10     list_per_page =  10
11 admin.site.register(Students, StudentsAdmin)
View Code

      执行动作位置  

         
 1 class StudentsAdmin(admin.ModelAdmin):
 2     def gender(self):
 3         if self.sgender:
 4             return ''
 5         else:
 6             return ''
 7     # 设置页面列的名称
 8     gender.short_description = "性别"
 9     list_display = ['pk', 'sname', 'sage', gender, 'scontend', 'sgrade', 'isDelete']
10     list_per_page =  10
11     # 执行动作的位置
12     actions_on_top = False
13     actions_on_bottom = True
14 admin.site.register(Students, StudentsAdmin)
View Code

    使用装饰器完成注册

       
 1 @admin.register(Students)
 2 class StudentsAdmin(admin.ModelAdmin):
 3     def gender(self):
 4         if self.sgender:
 5             return ''
 6         else:
 7             return ''
 8     # 设置页面列的名称
 9     gender.short_description = "性别"
10     list_display = ['pk', 'sname', 'sage', gender, 'scontend', 'sgrade', 'isDelete']
11     list_per_page =  10
12     # 执行动作的位置
13     actions_on_top = False
14     actions_on_bottom = True
15 # admin.site.register(Students, StudentsAdmin)
View Code

  10、视图的基本使用

    概述:在django中视图对web请求进行回应,视图就是一个python函数,在views.py文件中定义

    定义视图:

       
1 from django.http import HttpResponse
2 def index(request):
3     return HttpResponse("dylan is a good man")
View Code

    配置URL:

      修改project目录下的urls.py文件

         
1 from django.contrib import admin
2 from django.conf.urls import url,include
3 urlpatterns = [
4     url(r'^admin/', admin.site.urls),
5     url(r'^', include('myApp.urls')),
6 ]
View Code

      在myApp应用目录下创建一个urls.py文件

         
1 from django.conf.urls import url
2 from . import views
3 urlpatterns = [
4    url(r'^$', views.index)
5 ]
View Code

  11、模版的基本使用

    概述:模版是HTML页面,可以根据视图中传递过来的数据进行填充

    创建模版目录:创建templates目录,在目录下创建对应项目的模版目录(工程project/templates/myApp)

    配置模版路径:

      修改settings.py文件下的TEMPLATES,'DIRS': [os.path.join(BASE_DIR, 'templates')]

四、Django模型

  概述:Django对各种数据库提供了很好的支持,Django为这些数据库提供了统一的调用API,可以根据不同的业务需求选择不同的数据库

  配置数据库:

    修改工程目录下的__init__.py文件

     1 import pymysql
     2 pymysql.install_as_MySQLdb()

    修改settings.py文件

     1 DATABASES = {
     2     'default': {
     3         'ENGINE': 'django.db.backends.mysql',  
     4         'NAME': "ying",    
     5         'USER': 'root',
     6         'PASSWORD': '123456',
     7         'HOST': 'localhost',
     8         'PORT': '3306',
     9     }
    10 }

  开发流程:

    配置数据库

    定义模型类:一个模型类都在数据库中对应一张数据表

    生成迁移文件

    执行迁移文件生成数据表

    使用模型类进行增、删、改、查(简称crud)操作

  ORM:

    概述:对象--关系--映射

    任务:

      根据对象的类型生成表结构

      将对象、列表的操作转换成SQL语句

      将SQL语句查询到的结果转换为对象、列表

    优点:极大的减轻了开发人员的工作量。不需要面对因数据库的变更而修改代码

     图解:

      

  定义模型:

    模型、属性、表、字段间的关系:

      一个模型类在数据库中对应一张表,在模型类中定义的属性,对应该模型对照表中的一个字段

    定义属性: 

      
定义属性
	概述
		.django根据属性的类型确定以下信息
			.当前选择的数据表支持字段的类型
			.渲染管理表单时使用的默认html文件
			.在管理站点最低限度的验证

		.gjango会为表增加自动增长的主键列,每个模型只能有一个主键列,
		如果使用选项设置某属性为主键列后,则django不会再生成默认的主键列

		.属性命名限制
			.遵循标识符规则 
			.由于django的查询方式,不允许使用连续的下划线

	库
		.定义属性时,需要字段类型,字段类型被定义在django.db.models.fields
		目录下,为了方便使用,被导入到django.db.models中

		.使用方式
			.导入from django.db. import models
			.通过models.Field创建字段类型的对象,赋值给属性	

	逻辑删除
		.对于重要数据都要做逻辑删除,不做物理删除,实现方法是定义isDelete属性,
		类型为BooleanField,默认值为False

	字段类型
		.AutoField
			.一个根据实际ID自动增长的IntegerField,通常不指定如果不指定
			一个主键字段将自动添加到模型中

		.CharField(max_length=字符长度)
			.字符串,默认的表单样式是TextInput

		.TextField
			.大文本字段,一般超过4000使用,默认的表单控件是Textarea

		.IntegerField
			.整数

		.DecimalField(max_digits=None, decimal_places=None)
			.使用python的Decimal实例表示的十进制浮点数
			.参数说明
				.DecimalField.max_digits
					.位数总数
				.DecimalField.decimal_places
					.小数点后的数字位数	

		.FloatField
			.用python的float实例来表示的浮点数

		.BooleanField
			.true/false 字段,此字段的默认表单控制是CheckboxInput

		.NullBooleanField
			.支持null、true、false三种值

		.DateField([auto_now=False, auto_now_add=False])
			.使用python的datetime.date实例表示的日期
			.参数说明
				.DateField.auto_now
					.每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"
					的时间戳,它总是使用当前日期,默认为false
				.DateField.auto_now_add
					.当对象第一次被创建时自动设置为当前时间,用于创建的时间戳,它总是
					使用当前日期,默认为false
			.说明
				.该字段 默认对应的表单控件是一个TextInput,在管理员站点添加了一个
				JavaScript写的日历控件,和一个"Today"的快捷按钮,包含了一个额外的
				invalid_date错误消息键
			.注意
				.auto_now_add, auto_now, and default这些设置是相互排斥的,他们之间的
				任何组合将会发生错误的结果

		.TimeField
			.使用python的datetime.time实例表示的时间,参数同DateField 

		.DateTimeField
			.使用python的datetime.datetime实例表示的日期和时间,参数同DateField 

		.FileField
			.一个上传文件的字段

		.ImageField
			.继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image

	字段选项
		.概述
			.通过字段选项,可以实现对字段的约束
			.在字段对象时通过关键字参数指定

		.null
			.如果为True,Django将空值NULL存储到数据库中,默认值是False

		.blanke
			.如果为True,则该字段允许为空白,默认值是False

		.注意
			.null是数据库范畴的概念,blank是表单验证范畴的概念

		.db_column
			.字段的名称,如果未指定,则使用属性的名称

		.db_index
			.若值为True,则在表中会为此字段创建索引

		.default
			.默认值

		.primary_key
			.若为True,则该字段会成为模型的主键字段

		.unique
			.如果为True,这个字段在表中必须有唯一值

	关系
		.分类
			.ForeignKey:一对多,将字段定义在多的端中
			.ManyToManyField:多对多,将字段定义在两端中
			.OneToOneField:一对一,将字段定义在任意一端中

		.用一访问多
			.格式
				.对象.模型类小写_set
			.示例
				grade.students_set

		.用一访问一
			.格式
				.对象.模型类小写
			.示例
				.grade.students

		.访问id
			.格式
				.对象.属性_id
			.示例
				.student.sgrade_id
View Code

    创建模型类:

      
 1 class Students(models.Model):
 2     # 定义一个类方法创建对象,cls代表了Students类
 3     @classmethod
 4     def createStudent(cls, name, age, gender, contend, grade, lastT, createT, isD=False):
 5         stu = cls(sname=name, sage=age, sgender=gender, scontend=contend, sgrade=grade, lastTime=lastT,creatTime=createT, isDelete=isD)
 6         return stu
 7     # 自定义模型管理器
 8     # 当自定义模型管理器时,objects就不存在了
 9     stuObj = models.Manager()
10     stuObj2 = StudentsManager()
View Code

    元选项:

      在模型类中定义Meta类,用于设置元信息

      定义数据表名,推荐使用小写字母,如果不写,数据表名默认为项目名小写_类名小写

         
1 class Meta:
2     db_table="students"
3     ordering=['id']
View Code

      对象的默认排序字段,获取对象的列表时使用 

         
1 ordering=['id']    升序
2 ordering=['-id']   降序
View Code

        注意:排序会增加数据库的开销

    指定一个主键,创建表时就不会自动生成id

  模型成员:

    类属性:

      objects是Manager类型的一个对象,作用是与数据库进行交互,当定义模型类时没有指定管理器,则Django为模型创建一个名为objects的管理器

    自定义管理器:

      stuObj = models.Manager()

      当为模型指定模型管理器,Django就不再为模型类生成objects模型管理器

    自定义管理器Manager类:

      模型管理器是Django的模型与数据库进行交互的接口,一个模型可以有多个模型管理器

      作用:

        向管理器类中添加额外的方法

        修改管理器返回的原始查询集(重写get_queryset()方法)

      代码示例:

         
1 class StudentsManager(models.Manager):
2     def get_queryset(self):
3         return super(StudentsManager,self).get_queryset().filter(isDelete=False)
4 
5 class Students(models.Model):
6     # 自定义模型管理器
7     # 当自定义模型管理器时,objects就不存在了
8     stuObj = models.Manager()
9     stuObj2 = StudentsManager()
View Code

    创建对象:

      目的:向数据库中添加数据

      当创建对象时,Django不会对数据库进行读写操作,当调用save()方法时才与数据库交互,将对象保存到数据库表中

      注意:__init__()方法已经在父类models.Model中使用,在自定义的模型中无法使用

      方法:

        在模型类中增加一个类方法

           
1 class Students(models.Model):
2     # 定义一个类方法创建对象,cls代表了Students类
3     @classmethod
4     def createStudent(cls, name, age, gender, contend, grade, lastT, createT, isD=False):
5         stu = cls(sname=name, sage=age, sgender=gender, scontend=contend, sgrade=grade, lastTime=lastT,creatTime=createT, isDelete=isD)
6         return stu
View Code

        在定义管理器中添加一个方法

            
 1 class StudentsManager(models.Manager):
 2     def get_queryset(self):
 3         return super(StudentsManager,self).get_queryset().filter(isDelete=False)
 4     # 在管理器中添加一个方法
 5     def createStudent(self, name, age, gender, contend, grade, lastT, createT, isD=False):
 6         stu = self.model()
 7         stu.sname = name
 8         stu.sage = age
 9         stu.sgender = gender
10         stu.scontend = contend
11         stu.sgrade = grade
12         stu.lastTime = lastT
13         stu.creatTime = createT
14         stu.isDelete = isD
15         return stu
View Code

  模型查询:

    概述:  

      查询集:表示从数据库中获取的对象集合

      查询集可以有多个过滤器

      过滤器就是一个函数,基于所给的参数限制查询集结果

      从sql角度来说,查询集和select语句等价,过滤器就像where条件

    查询集:

      在管理器上调用过滤器方法返回查询集

      查询集经过过滤器筛选后产生新的查询集,所以可以写成链式调用

      惰性执行:创建查询集不会带来任何数据的访问,直到调用数据时,才会访问数据

      直接访问数据的情况:迭代、序列化、与if合用

      返回查询集的方法称为过滤器

         
1 all():返回查询集中的所有数据
2 filter():返回符合条件的数据
3     filter(键=值)
4     filter(键=值,键=值)
5     filter(键=值).filter(键=值)
6 exclude():过滤掉符合条件的数据
7 order_by():排序
8 values():一条数据就是一个对象(字典),返回一个列表
View Code

      返回单个数据

         
1 get():返回一个满足条件的对象
2     注意:如果没有找到符合条件的对象,会引发"模型类.DoesNotExist"异常;如果找到多个对象,会引发"模型类.MultipleObjectsReturned"异常
3 count():返回当前查询集中的对象个数
4 first():返回当前查询集中的第一个对象
5 last():返回当前查询集中的最后一个对象
6 exists():判断查询集中是否有数据,如果有数据返回True,否则返回False
7             
View Code

      限制查询集:查询集返回列表,可以使用下标的方法进行限制,等同于sql中的limit语句

        studentsList = Students.stuObj2.all()[0:5]

        注意:下表不能是负数

      查询集的缓存:

        概述:每个查询集都包含一个缓存,来最小化的对数据库访问;在新建的查询集中,缓存首次为空,第一次对查询集求值,会发生数据缓存。django会将查询出来                                         的数据做一个缓存,  并返回查询结果,以后的查询直接使用查询集的缓存

      字段查询:

        概述:实现了sql中的where语句,作为方法filter()、exclude()、get()的参数

        语法:属性名称__比较运算符=值

        外键:属性名_id

        转义:like语句中使用%是为了匹配占位。匹配数据中的%(where like "\%")

        比较运算符:

          exact:判断,大小写敏感
          contains:是否包含,大小写敏感
          startswith:以value开头,大小写敏感
          endswith:以value结尾,大小写敏感
          以上四个在前面加上 i,就表示不区分大小写iexact、icontains、istartswith、iendswith
          isnull、isnotnull:是否为空
          in:是否包含在范围内
          gt、gte、lt、lte:大于、大于等于、小于、小于等于
          year、month 、day、week_day、hour、minute、second
          跨关联查询:
              处理join查询:
                  语法:模型类名_属性名_比较运算符
          查询快捷:pk(代表的是主键)

        聚合函数:

          使用aggregate()函数返回聚合函数的值,还有Avg()、Count()、Max()、Min()、Sum()

        F对象:可以使用模型的A属性与B属性进行比较

            
1 from django.db.models import F
2 def grades(request):
3     g = Grades.objects.filter(ggirlnum__gt=F('gboynum'))
4     print(g)
5     return HttpResponse("************")
6 
7 支持F对象的算术运算:
8     g = Grades.objects.filter(ggirlnum__gt=F('gboynum')+20)
View Code

        Q对象:

          概述:过滤器的方法中的关键字参数,条件为And模式

          需求:进行or查询

          解决:使用Q对象 

              
1 from django.db.models import Q
2 studentsList = Students.stuObj2.filter(Q(pk__lt=3) | Q(sage__gt=50))
3 studentsList = Students.stuObj2.filter(Q(pk__lt=3)) #只有一个Q对象,就是用于匹配的
4 studentsList = Students.stuObj2.filter(~Q(pk__lt=3)) #取反
View Code    
原文地址:https://www.cnblogs.com/ccmldl/p/9606388.html