ORM全拼:Object-Relation-Mapping翻译就是对象关系映射。在MVC/MTV设计模式中的Model模块中都包括ORM。主要实现模型对象到关系数据库数据的映射。好比:把数据库表中每条记录映射为一个模型对象html
优势:python
只须要面向对象编程,不须要面向数据库编写代码。对数据库的操做都转化为对类属性和方法的操做,不用编写各类数据库的sql语句mysql
实现了数据模型与数据库的解耦,屏蔽了不一样数据库操做上的差别。经过简单地配置就能够轻松更换数据库,而不须要修改代码。git
缺点:sql
相比较直接使用SQL语句操做数据库,有性能缺失。会转化为sql语句在执行。多了流程。根据对象的操做转换成sql语句,根据查询的结果转化成对象,在映射过程当中有性能损失。数据库
一、建立项目django
django-admin startproject BookManager
二、建立应用编程
python manage.py startapp Book
三、安装应用设计模式
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'Book', ]
四、本地化浏览器
LANGUAGE_CODE = 'zh-Hans' TIME_ZONE = 'Asia/Shanghai'
五、建立模板路径
在应用同级目录下,建立templates模板文件
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', #模板路径 'DIRS': [os.path.join(BASE_DIR,"templates")], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
六、应用中分发路由
from django.contrib import admin from django.urls import path from Book import views urlpatterns = [ path('admin/', admin.site.urls), path('booklist/', views.bookList), ]
七、准备视图函数
from django.shortcuts import render from django.http import HttpResponse # Create your views here. #书籍列表信息视图 def bookList(request): return HttpResponse("ok")
八、开启服务器,测试项目
python manage.py runserver
http://127.0.0.1:8000/
Django项目默认采用sqlite3数据库,可是Web项目首选的数据库是mysql数据库,因此咱们须要修改Django项目默认的数据库为mysql数据库
pymysql包用于跟mysql数据库交互,没有pymysql包会报错:Error loading MySQLdb module: No module named MySQLdb
pip3 install pymysql
pymysql包配置:
默认配置:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
配置mysql数据库:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 数据库引擎 'NAME': 'Bookdb', # 数据库名称 'HOST': 'localhost', # 数据库主机(建议使用主机真实IP) 'PORT': '3306', # 数据库端口 'USER': 'root', # 数据库用户名 'PASSWORD': '', # 数据库密码 } }
打开cmd终端,打开数据库,连接数据库。建立数据库名字:
create database bookdb charset=utf8;
use Bookdb;
show tables;
#退出数据库 exit
当为项目建立好mysql类型的数据库bookdb后,须要建立模型类并生成和执行迁移表,从而建立数据库表。可是在建立模型类须要指定模型属性和属性类型。
模型属性和属性类型,也就是对应数据库中的字段和字段类型
# 书籍信息模型 class Book(models.Model): name = models.CharField(max_length=20) #图书名称
备注:属性名一、不容许使用python的保留关键字,二、不容许使用mysql的保留关键字,三、不容许使用连续的下划线,由于Django的查询语法就是连续的下划线。
AutoField:自动增加的IntegerField,一般不用指定,不指定时Django会自动建立属性名为id的自动增加属性
BooleanField:布尔字段,值为True或False
NullBooleanField:支持Null、True、False三种值
CharField(max_length=字符长度):字符串参数max_length表示最大字符个数
TextField:大文本字段,通常超过4000个字符时使用
IntegerField:整数
DecimalField(max_digits=None, decimal_places=None):能够指定精度的十进制浮点数 参数max_digits表示总位数 参数decimal_places表示小数位数
FloatField:浮点数
DateField[auto_now=False, auto_now_add=False]):日期,参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,
它老是使用当前日期,默认为false 参数auto_now_add表示当对象第一次被建立时自动设置当前时间,用于建立的时间戳,它老是使用当前日期,默认为false 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误
TimeField:时间,参数同DateField
DateTimeField:日期时间,参数同DateField
FileField:上传文件字段
ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片
经过选项实现对字段的约束
null:若是为True,表示容许为空,默认值是False
blank:若是为True,则该字段容许为空白,默认值是False
对比:null是数据库范畴的概念,blank是表单验证范畴的
db_column:字段的名称,若是未指定,则使用属性的名称
db_index:若值为True, 则在表中会为此字段建立索引,默认值是False
default:默认值
primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,通常做为AutoField的选项使用
unique:若是为True, 这个字段在表中必须有惟一值,默认值是False
注意:Django会自动为表建立主键字段
若是使用选项设置某属性为主键字段后,Django不会再建立自动增加的主键字段
默认建立的主键字段为id,可使用pk代替,pk全拼为primary key
关系型数据库的关系包括三种类型:
ForeignKey:一对多,将字段定义在多的一端中
ManyToManyField:多对多,将字段定义在任意一端中
OneToOneField:一对一,将字段定义在任意一端中
能够维护递归的关联关系,使用self指定,详见“自关联”
做用:在模型类中定义 元类Meta,用于设置元信息,用db_table 自定义表的名字
# 书籍信息模型 class BookInfo(models.Model): name = models.CharField(max_length=20) #图书名称 class Meta: #元信息类 db_table = 'bookinfo' #自定义表的名字
#在数据库中更改表名
desc 代表
定义的模型能够是这个样子
#书籍信息 ("与时间作朋友","2002-08-22","45.21","中信出版社","athor_id") #人物信息 ("李笑来","男","年龄","家庭地址","电话")
所以模型代码以下:
from django.db import models # Create your models here. #建立做者信息表 class Authors(models.Model): name = models.CharField(max_length=20)#做者名字 gender = models.BooleanField(default=True)#性别 age = models.IntegerField()#年龄 addr = models.CharField(max_length=60) tel = models.IntegerField() #元类修改表名 class Meta: db_table = "authors" #建立书籍信息 class Books(models.Model): name = models.CharField(max_length=20)#书名 pub_data = models.DateField(null=True)#出版日期 #参数max_digits表示总位数 参数decimal_places表示小数位数 price = models.DecimalField(max_digits=8,decimal_places=2)#价格 publish = models.CharField(max_length=20) #外键 将字段定义在多的一端中 级联删除 author = models.ForeignKey(Authors,on_delete=models.CASCADE) #修改表名(元类) class Meta: db_table = "books"
模型迁移不要忘记:
python manage.py makemigrations
python manage.py migrate
查看表结构:
去站点插点数据(若是嫌慢就用sql语句插数据)(须要设置站点,一、注册管理模型类,须要显示完整的,重写类,list_display从新注册,启动超级用户,python manage.py createsuperuser)
网址:http://127.0.0.1:8000/booklist
路由部分:
from django.contrib import admin from django.urls import path from Book import views urlpatterns = [ path('admin/', admin.site.urls), path('booklist/', views.bookList), ]
视图部分:
from django.shortcuts import render from django.http import HttpResponse # Create your views here. from Book.models import * #书籍列表信息视图 def bookList(request): #查询数据库书籍信息 booklist = Books.objects.all() #构造上下文 content = {"booklist":booklist} #传入模板 返回由视图发送给浏览器 return render(request,"Book/booklist.html",content)
模板部分:
from django.db import models # Create your models here. #建立做者信息表 class Authors(models.Model): name = models.CharField(max_length=20)#做者名字 gender = models.BooleanField(default=True)#性别 age = models.IntegerField()#年龄 addr = models.CharField(max_length=60) tel = models.IntegerField() #元类修改表名 class Meta: db_table = "authors" def __str__(self): return self.name #建立书籍信息 class Books(models.Model): name = models.CharField(max_length=20)#书名 pub_data = models.DateField(null=True)#出版日期 #参数max_digits表示总位数 参数decimal_places表示小数位数 price = models.DecimalField(max_digits=8,decimal_places=2)#价格 publish = models.CharField(max_length=20) #外键 将字段定义在多的一端中 级联删除 author = models.ForeignKey(Authors,on_delete=models.CASCADE) #修改表名(元类) class Meta: db_table = "books" def __str__(self): return self.name
结果:
str : 在将对象转换成字符串时会被调用
save : 将模型对象保存到数据库表中
delete : 将模型对象从数据库表中删除
objects模型属性
objects : 管理器对象是Manager类型的对象,定义在from django.db import models中用于模型对象和数据库交互
是默认自动生成的属性,可是能够自定义管理器对象自定义管理器对象后,Django再也不生成默认管理器对象objects
自定义管理器对象,本来默认的是objects = models.Manager(),能够自定义,从新实例化管理器对象。
all():返回全部的数据
filter():返回知足条件的数据
exclude():返回知足条件以外的数据,至关于sql语句中where部分的not关键字
order_by():返回排序后的数据
get():返回单个知足条件的对象 若是未找到会引起"模型类.DoesNotExist"异常 若是多条被返回,会引起"模型类.MultipleObjectsReturned"异常 count():返回当前查询的总条数 aggregate():聚合 exists():判断查询集中是否有数据,若是有则返回True,没有则返回False
一、惰性执行:建立查询集不会访问数据库,直到在模板中调用数据时,才会访问数据库。
调用数据的状况包括迭代、序列化、与if合用
二、缓存:查询集的结果被存下来以后,再次查询相同数据时会使用以前缓存的数据
每一个查询集都包含一个缓存来最小化对数据库的访问,第一次查询数据后,Django会将查询集缓存起来,并返回请求的结果,再次查询相同数据时将重用缓存的结果。
若是获取一个对象,直接使用[0]
,等同于[0:1].get()
[0]
引起IndexError
异常,[0:1].get()
引起DoesNotExist
异常filter(模型属性__条件运算符=值) 例: filter(name__contains='时')
说明:查询语句是属性名称和比较运算符间使用两个下划线相连,因此定义的模型属性名不能包括多个下划线
实现sql中where的功能,能够调用过滤器filter()、exclude()、get()
# 1.查询id为1的书籍 # 2.查询书名包含‘时间’的书籍 # 3.查询书名以‘观’结尾的书籍 # 4.查询书名不为空的书籍 # 5.查询价格为50或52的书籍 # 6.查询价格大于52的书籍 # 7.查询id不等于3的书籍 # 8.查询2019年发表的书籍 # 9.查询2000年1月1往后发表的书籍
1.查询id为1的书籍(exact:判断相等)
#一、查询id为1的书籍(exact: 判断相等)<QuerySet [<Books: 与时间作朋友>]>
book = Books.objects.all()
book1 = book.filter(id__exact=1)
2.查询书名包含‘时间’的书籍(contains:是否包含)
book = Books.objects.all() book1 = book.filter(name__contains="局观")
#<QuerySet [<Books: 大局观>]>
3.查询书名以‘与’开始的书籍(startswith,endswith)
book = Books.objects.all() book1 = book.filter(name__startswith="与") print(book1)
4.查询书名不为空的书籍(isnull:是否为null)
book = Books.objects.all() book1 = book.filter(name__isnull=False) print(book1)
5.查询价格为50或52的书籍(in:是否包含在这范围内)
book = Books.objects.all() book1 = book.filter(price__in=[50,52]) print(book1)
6.查询价格大于52的书籍(gt,gte,it,ite:大于,大于等于,小于,小于等于)
book = Books.objects.all() book1 = book.filter(price__gt=52) print(book1)
7.查询id不等于3的书籍(exclude:条件之外的数据)
book = Books.objects.all() book1 = book.exclude(id=3) print(book1)
8.查询2019年发表的书籍(year\month\day\week_day\hour\minute\second:对日期时间类型的属性进行运算)
book = Books.objects.all() book1 = book.filter(pub_data__year=2019) print(book1)
9.查询2000年1月1往后发表的书籍
from datetime import date book = Books.objects.all() book1 = book.filter(pub_data__gt=date(2000,1,1)) print(book1)
备注:
exact
、contains
、startswith
、endswith
运算符都区分大小写i
表示不区分大小写iexact
、icontains
、istartswith
、iendswith
其余特殊查询下一节分享总结(F和Q查询,聚合函数,关联查询)