O(objects):类和对象。
R(Relation):关系,关系数据库中的表格。
M(Mapping):映射。
Django ORM框架的功能:
a) 建立模型类和表之间的对应关系,允许我们通过面向对象的方式来操作数据库。
b) 根据设计的模型类生成数据库中的表格。
c) 通过方便的配置就可以进行数据库的切换。
今天演示使用MySQL数据库,这是Web项目首选的数据库。
进入虚拟环境dj_py3
workon dj_py3
创建项目demo2。
django-admin startproject demo2
创建应用
python manage.py startapp news
注册应用,打开demo2/settings.py文件,将应用添加进去
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
登录mysql
数据库:
mysql –uroot –p
查看有哪些数据库:
show databases
创建数据库:
create database test2 charset=utf8
#切记:指定编码
使用数据库:
use dj_py3;
查看数据库中的表:
show tables;
修改settings.py中的DATABASES。(注意:根据自己Mysql数据库做修改!!!!!)
DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql', # 设置使用mysql数据库
'NAME':'dj_py3', # 指定数据库
'USER':'root', # 用户名
'PASSWORD':'mysql', #数据库所在主机的ip
'PORT':3306, #端口号
'HOST':'localhost'
}
}
注意:django框架,只能生产数据表,不会自动帮我们生成mysql数据库,所以我们需要自己去创建。
需要安装操作mysql数据库的包,python2环境和python3环境有以下区别。
a) **python2****需要安装mysql-python:
pip install mysql-python
b) python3需要安装pymysql:
pip install pymysql
python3中安装好pymysql,需要在demo2/init.py中加如下内容:
import pymysql
pymysql.install_as_MySQLdb()
模型类设计,在昨天的基础上增加属性read和comment,另外设置软删除标记属性isDelete。
软删除标记:删除数据时不做真正的删除,而是把标记数据设置为1表示删除,目的是防止重要的数据丢失。
models.py代码如下
from django.db import models
class NewsInfo(models.Model):
title = models.CharField(max_length=50) #标题
context = models.TextField() #内容
b_date = models.DateField() #日期
read =models.IntegerField() #阅读量
comment = models.IntegerField() # 评论数
is_delete = models.BooleanField(default=0) #逻辑删除
生成迁移:python manage.py makemigrations
执行迁移 :python manage.py migrate
注册模型类:打开应用目录下的admin.py文件,编写代码如下
from django.contrib import admin
# Register your models here.
from .models import NewsInfo
class NewsInfoAdmin(admin.ModelAdmin):
list_display = ['id','title','b_date']
admin.site.register(NewsInfo,NewsInfoAdmin)
创建管理员账号:python manage.py createsuperuser
启动项目:python manage.py runserver 主机ip:端口号
登录站点管理,添加数据
同样我们先分为两个页面,一个新闻列表展示页,一个详情页
创建视图函数
打开views.py,创建index视图函数
from django.shortcuts import render
# Create your views here.
from .models import NewsInfo
def index(request):
news_list = NewsInfo.objects.all()
context={'news_list':news_list}
return render(request,'templates/index',context)
配置urls,
在应用目录下创建一个urls.py文件,url配置代码如下
from django.conf.urls import url,include
from .views import *
urlpatterns = [
url(r'^$',include(index)),
url(r'^index',include(index)),
]
然后再demo/urls.py里面,加入一行代码关联到应用的urls配置
url(r'^',include('news.urls'))
创建模板目录:在项目目录下,创建templates目录,再在templates目录中创建一个和应用同名的目录news,
配置模板路径:在想项目目录的stttings.py下面,对TEMPLATES里的DIRS项,进行修改
'DIRS': [os.path.join(BASE_DIR,'templates')]
创建模板:在news下创建index.html模板文件。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页title>
head>
<body>
<h1>{{h1}}h1>
{%for news in news_list%}
<li><a href="/{{news.id}}">{{news.title}}a>{{news.b_date}}li>
<br>
{%endfor%}
body>
html>
1、编写视图函数
2、配置url
3、创建模板
django会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后django不会再创建自动增长的主键列。
默认创建的主键列属性为id,可以使用pk代替,pk全拼为primary key。
1)不能是python的保留关键字。
2)不允许使用连续的下划线,这是由django的查询方式决定的。
3)定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
属性名=models.字段类型(选项)
使用时需要引入django.db.models包,字段类型如下:
类型 | 描述 |
---|---|
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]) | 日期。1)参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false。2) 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false。3)参数auto_now_add和auto_now是相互排斥的,组合将会发生错误。 |
TimeField | 时间,参数同DateField。 |
DateTimeField | 日期时间,参数同DateField。 |
FileField | 上传文件字段。 |
ImageField | 继承于FileField,对上传的内容进行校验,确保是有效的图片。 |
通过选项实现对字段的约束,选项如下:
选项名 | 描述 |
---|---|
default | 默认值。设置默认值。 |
primary_key | 若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用。 |
unique | 如果为True, 这个字段在表中必须有唯一值,默认值是False。 |
db_index | 若值为True, 则在表中会为此字段创建索引,默认值是False。 |
db_column | 字段的名称,如果未指定,则使用属性的名称。 |
null | 如果为True,表示允许为空,默认值是False。 |
blank | 如果为True,则该字段允许为空白,默认值是False。 |
对比:null是数据库范畴的概念,blank是后台管理页面表单验证范畴的。
经验:
当修改模型类之后,如果添加的选项不影响表的结构,则不需要重新做迁移,商品的选项中default和blank不影响表结构。
参考文档:
**http://python.usyiyi.cn/translate/django_182/index.html**
1、在models.py中定义一个新闻类别的模型类
class TypeInfo(models.Model):
new_type=models.CharField(max_length=20)
2、再次生成迁移:python manage.py makegimrations
改:python manage.py makemigrations
3、执行迁移:python manage.py migrate
4、打开mysql数据库,往上面的模型类生成的news_typeinfo表中插入下面的数据
insert into news_typeinfo(new_type) values('国内新闻'),('国际新闻'),('体育新闻'),('财经资讯'),('科技资讯'),('娱乐头条'),('互联网资讯'),('汽车快报'),('热点新闻');
mysql.log是mysql的日志文件,里面记录的对MySQL数据库的操作记录。默认情况下mysql的日志文件没有产生,需要修改mysql的配置文件,步骤如下:
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
windows下:(进入数据库操作)
查看日
SHOW VARIABLES LIKE "general_log%";
启用日志
SET GLOBAL general_log = 'ON';
参考:MYSQL启用日志,和查看日志
2)重启mysql服务,就会产生mysql日志文件。
sudo service mysql restart
3)打开MySQL的日志文件。
/var/log/mysql/mysql.log
是mysql日志文件所在的位置。
使用下面的命令可以实时查看mysql的日志文件:
sudo tail -f /var/log/mysql/mysql.log
通过模型类.objects属性可以调用如下函数,实现对模型类对应的数据表的查询。
函数名 | 功能 | 返回值 | 说明 |
---|---|---|---|
get | 返回表中满足条件的一条且只能有一条数据。 | 返回值是一个模型类对象。 | 参数中写查询条件。1) 如果查到多条数据,则抛异常MultipleObjectsReturned。2)查询不到数据,则抛异常:DoesNotExist。 |
all | 返回模型类对应表格中的所有数据。 | 返回值是QuerySet类型 | 查询集 |
filter | 返回满足条件的数据。 | 返回值是QuerySet类型 | 参数写查询条件。 |
exclude | 返回不满足条件的数据。 | 返回值是QuerySet类型 | 参数写查询条件。 |
order_by | 对查询结果进行排序。 | 返回值是QuerySet类型 | 参数中写根据哪些字段进行排序。 |
启动项目,进入交互环境
python manage.py shell
导入models模块,
>>> from news.models import *
条件格式:
**模型类属性名__条件名=值**
判等条件名:exact
例:查询id为1的数据。
(注意:NewsInfo表中无数据,可改为TypeInfo)
NewsInfo.objects.get(id__exact=1)
判断等于的情况下可以把id__exact
,简写为id
NewsInfo.objects.get(id=1)
get:
例:查询id为3的新闻信息。
>>> NewsInfo.objects.get(id=3)
<NewsInfo: NewsInfo object>
all:
例:查询所有新闻数据
>>> NewsInfo.objects.all()
[<NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>]
filter:
查询新闻阅读量为9999的新闻数据:
>>> NewsInfo.objects.filter(read=9999)
[<NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>]
模糊条件查询
包含:contains
例:查询名称里包含’娱乐’的新闻类别。
>>> TypeInfo.objects.filter(new_type__contains='娱乐')
[<TypeInfo: TypeInfo object>]
开头:starswith
例:查询以’国’开头的新闻类别
>>> TypeInfo.objects.filter(new_type__startswith='国')
[<TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>]
结尾:endswith
例:查询以’资讯’结尾的新闻类别
>>> TypeInfo.objects.filter(new_type__endswith='资讯')
[<TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>]
不等于:exclude
例:查询所有id不等于1的新闻数据
>>> NewsInfo.objects.exclude(id=1)
[<NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>]
排序:roder_by
例:查询所有新闻数据并且按id进行排序(从小到大)
>>> NewsInfo.objects.all().order_by('id')
[<NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>]
例:查询所有新闻数据并且按id进行排序(从大到小)
>>> NewsInfo.objects.all().order_by('-id')
[<NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>]
范围查询:in
例:查询id为1或3或5的新闻类别。
>>> TypeInfo.objects.filter(id__in=[1,3,5])
[<TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>]
比较查询:
大于:gt
小于:lt
大于等于: gte
**小于等于:lte **
例:查询id小于3的新闻类别。
>>> TypeInfo.objects.filter(id__lt=3)
[<TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>]
空查询: isnull
例:查询类名不为空的新闻类别。 (False不为空,True为空)
>>> TypeInfo.objects.filter(new_type__isnull=False)
[<TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>, <TypeInfo: TypeInfo object>]
**作用:**用于类属性之间的比较。
之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢? 答:使用F对象,被定义在django.db.models中。
语法如下:
F(属性名)
例:查询阅读量大于等于评论量的新闻。
from django.db.models import F
...
list = NewsInfo.objects.filter(read__gte=F('comment'))
可以在F对象上使用算数运算。
例:查询阅读量大于2倍评论量的图书。
list = NewsInfo.objects.filter(read__gt=F('comment') * 2)
**作用:**用于查询时条件之间的逻辑关系。 and or not,可以对Q对象进行& | ~ 操作。
使用之前需要先导入:
from django.db.models import Q
and:&
例:查询阅读量大于300且评论量大于10的新闻的数据。
>>> NewsInfo.objects.filter(read__gt=300,comment__gt=10)
[<NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>]
#使用Q对象
>>> NewsInfo.objects.filter(Q(read__gt=3)&Q(comment__gt=10))
[<NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>]
or:|
例:查询id大于3或者阅读量大于30的新闻的信息。
>>> NewsInfo.objects.filter(Q(read__gt=3)|Q(comment__gt=10))
[<NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>]
not:~
例:查询id不等于2的新闻信息。
>>> NewsInfo.objects.filter(~Q(id=2))
[<NewsInfo: NewsInfo object>, <NewsInfo: NewsInfo object>]
**作用:**对查询结果进行聚合操作。
求和:sum
计数:count
平均值:avg
最大值:max
最小值:min
aggregate:调用这个函数来使用聚合。 返回值是一个字典
使用前需先导入聚合类:
from django.db.models import Sum,Count,Max,Min,Avg
例:查询所有新闻类别的总数
#查询所有新闻类别的总数
>>> TypeInfo.objects.all().aggregate(Count('id'))
{'id__count': 9}
# 查询所有新闻阅读量的总和
>>> NewsInfo.objects.all().aggregate(Sum('read'))
{'read__sum': 29997}
# 使用注意点aggregate里面的函数,第一个字母要大写,属性项也要用引号括起来
直接使用聚合函数查询返回值是一个数字
例:查询所有新闻类别的总数。
>>> TypeInfo.objects.count()
9
# 统计id大于3的新闻类别数
>>> TypeInfo.objects.filter(id__gt=3).count()
6
小结:
![img](file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2B96.tmp.jpg)
参考文档:
http://python.usyiyi.cn/translate/django_182/ref/models/querysets.html
all, filter, exclude, order_by调用这些函数会产生一个查询集,QuerySet类对象可以继续调用上面的所有函数。
1) 惰性查询:只有在实际使用查询集中的数据的时候才会发生对数据库的真正查询。
2) 缓存:当使用的是同一个查询集时,第一次使用的时候会发生实际数据库的查询,然后把结果缓存起来,之后再使用这个查询集时,使用的是缓存中的结果。
可以对一个查询集进行取下标或者切片操作来限制查询集的结果。
对一个查询集进行切片操作会产生一个新的查询集,下标不允许为负数。
取出查询集第一条数据的两种方式:
方式 | 说明 |
---|---|
b[0] | 如果b[0]不存在,会抛出IndexError异常 |
b[0:1].get() | 如果b[0:1].get()不存在,会抛出DoesNotExist异常。 |
exists:判断一个查询集中是否有数据。True False
关系型数据库的关系包括三种类型:
准备:
创建项目django-admin startproject demo2
创建应用news :python manage.py startapp news
创建应用books :python manage.py startapp books
在settings.py里面注册应用
在settiing里面设置数据库的信息
参见books应用中的BookInfo类和HeroInfo类。
#定义图书模型类BookInfo
class BookInfo(models.Model):
btitle = models.CharField(max_length=20)#图书名称
b_date = models.DateField()#发布日期
bread = models.IntegerField(default=0)#阅读量
bcomment = models.IntegerField(default=0)#评论量
is_delete = models.BooleanField(default=False)#逻辑删除
#定义英雄模型类HeroInfo
class HeroInfo(models.Model):
hname = models.CharField(max_length=20)#英雄姓名
hgender = models.BooleanField(default=True)#英雄性别
is_delete = models.BooleanField(default=False)#逻辑删除
hcomment = models.CharField(max_length=200)#英雄描述信息
hbook = models.ForeignKey('BookInfo')#英雄与图书表的关系为一对多,所以属性定义在英雄模型类中
我们下面设计一个新闻类和新闻类型类,一个新闻类型下可以用很多条新闻,一条新闻也可能归属于多种新闻类型。
重新在项目demo2下新建一个应用news,注册应用之后,编辑news/models.py文件设计模型类。
class TypeInfo(models.Model):
tname = models.CharField(max_length=20) #新闻类别
class NewsInfo(models.Model):
ntitle = models.CharField(max_length=60) #新闻标题
ncontent = models.TextField() #新闻内容
npub_date = models.DateTimeField(auto_now_add=True) #新闻发布时间
ntype = models.ManyToManyField('TypeInfo') #通过ManyToManyField建立TypeInfo类和NewsInfo类之间多对多
(注意!!!!!
new中admin.py需修改 +删除 migrations文件下迁移文件(0001XXX开头)+清空数据内的表)
from django.contrib import admin
from .models import NewsInfo
class NewsInfoAdmin(admin.ModelAdmin):
list_display = ['id','ntitle','npub_date']
admin.site.register(NewsInfo,NewsInfoAdmin)
生成迁移:python manage.py makemigrations
执行迁移:python manage.py migrate
数据准备:
在数据库命令行中,复制如下语句执行,向books_bookinfo
表中插入测试数据:
insert into booktest_booksinfo(btitle,bpub_date,bread,bcomment,isDelete) values
('射雕英雄传','1980-5-1',12,34,0),
('天龙八部','1986-7-24',36,40,0),
('笑傲江湖','1995-12-24',20,80,0),
('雪山飞狐','1987-11-11',58,24,0);
改:
insert into books_bookinfo(btitle,b_date,bread,bcomment,is_delete) values
('射雕英雄传','1980-5-1',12,34,0),
('天龙八部','1986-7-24',36,40,0),
('笑傲江湖','1995-12-24',20,80,0),
('雪山飞狐','1987-11-11',58,24,0);
再复制如下语句执行,向booktest_heroinfo
表中插入测试数据:
insert into booktest_heroinfo(hname,hgender,hbook_id,hcomment,isDelete) values
('郭靖',1,1,'降龙十八掌',0),
('黄蓉',0,1,'打狗棍法',0),
('黄药师',1,1,'弹指神通',0),
('欧阳锋',1,1,'蛤蟆功',0),
('梅超风',0,1,'九阴白骨爪',0),
('乔峰',1,2,'降龙十八掌',0),
('段誉',1,2,'六脉神剑',0),
('虚竹',1,2,'天山六阳掌',0),
('王语嫣',0,2,'神仙姐姐',0),
('令狐冲',1,3,'独孤九剑',0),
('任盈盈',0,3,'弹琴',0),
('岳不群',1,3,'华山剑法',0),
('东方不败',0,3,'葵花宝典',0),
('胡斐',1,4,'胡家刀法',0),
('苗若兰',0,4,'黄衣',0),
('程灵素',0,4,'医术',0),
('袁紫衣',0,4,'六合拳',0);
改:
insert into books_heroinfo(hname,hgender,hbook_id,hcomment,is_delete) values
('郭靖',1,1,'降龙十八掌',0),
('黄蓉',0,1,'打狗棍法',0),
('黄药师',1,1,'弹指神通',0),
('欧阳锋',1,1,'蛤蟆功',0),
('梅超风',0,1,'九阴白骨爪',0),
('乔峰',1,2,'降龙十八掌',0),
('段誉',1,2,'六脉神剑',0),
('虚竹',1,2,'天山六阳掌',0),
('王语嫣',0,2,'神仙姐姐',0),
('令狐冲',1,3,'独孤九剑',0),
('任盈盈',0,3,'弹琴',0),
('岳不群',1,3,'华山剑法',0),
('东方不败',0,3,'葵花宝典',0),
('胡斐',1,4,'胡家刀法',0),
('苗若兰',0,4,'黄衣',0),
('程灵素',0,4,'医术',0),
('袁紫衣',0,4,'六合拳',0);
在上面我们定义了一个一对多的关系,定义了一个多对多的模型类,那么接下来我们进入到项目的shell里面开始练习关联查询
python manage.py shell
在定义模型类时,可以指定三种关联关系,最常用的是一对多关系,如本例中的"图书-英雄"就为一对多关系,接下来进入shell练习关系的查询。
添加引入:
python manage.py shell
# 导入models模块,
from news.models import *
from books.models import *
由一到多的访问语法:
# 一对应的模型类对象.多对应的模型类名小写_set
例:
b = BookInfo.objects.get(id=1)
b.heroinfo_set.all()
由多到一的访问语法:
#多对应的模型类对象.多对应的模型类中的关系类属性名
例:
h = HeroInfo.objects.get(id=1)
h.hbook
访问一对应的模型类关联对象的id语法:
#多对应的模型类对象.关联类属性_id
例:
h = HeroInfo.objects.get(id=1)
h.book_id
python manage.py shell
例:查询编号为1的图书。
book=BookInfo.objects.get(pk=1)
例:获得book图书的所有英雄。
book.heroinfo_set.all()
例:获得编号为1的英雄。
hero=HeroInfo.objects.get(pk=1)
例:获得hero英雄出自的图书。
hero.hbook
由多模型类条件查询一模型类数据:
语法如下:
关联模型类名小写__属性名__条件运算符=值
如果没有"__运算符"部分,表示等于,结果和sql中的inner join相同。
例:查询图书,要求图书中英雄的描述包含’八’。
list = BookInfo.objects.filter(heroinfo__hcontent__contains='八')
改:
list = BookInfo.objects.filter(heroinfo__hcomment__contains='八')
由一模型类条件查询多模型类数据: 语法如下:
一模型类关联属性名__一模型类属性名__条件运算符=值
例:查询书名为“天龙八部”的所有英雄。
list = HeroInfo.objects.filter(hbook__btitle='天龙八部')
对于地区信息、分类信息等数据,表结构非常类似,每个表的数据量十分有限,为了充分利用数据表的大量数据存储功能,可以设计成一张表,内部的关系字段指向本表的主键,这就是自关联的表结构。
打开booktest/models.py文件,定义AreaInfo类。
说明:关系属性使用self指向本类,要求null和blank允许为空,因为一级数据是没有父级的。
#定义地区模型类,存储省、市、区县信息
class AreaInfo(models.Model):
atitle=models.CharField(max_length=30)#名称
aParent=models.ForeignKey('self',null=True,blank=True)#关系
迁移。
python manage.py makemigrations
python manage.py migrate
打开mysql命令行,导入数据。
source areas.sql
打开booktest/views.py文件,定义视图area。
from books.models import AreaInfo
...
#查询广州市的信息
def area(request):
area = AreaInfo.objects.get(id=440100)
return render(request, 'booktest/area.html', {'area': area})
打开booktest/urls.py文件,新建一条url。
urlpatterns = [
...
url(r'^area/$', views.area),
]
改:
from django.conf.urls import url,include
from .views import *
urlpatterns = [
# url(r'^$',area),
url(r'^area',area),
]
在templates/booktest目录下,新建area.html文件。
<html>
<head>
<title>地区title>
head>
<body>
当前地区:{{area.atitle}}
<hr/>
上级地区:{{area.aParent.atitle}}
<hr/>
下级地区:
<ul>
{%for a in area.areainfo_set.all%}
<li>{{a.atitle}}li>
{%endfor%}
ul>
body>
html>
运行服务器。
python manage.py runserver
或:
python manage.py runserver 192.168.93.169:7777
http://192.168.93.169:7777/area
属性objects:管理器,是models.Manager类型的对象,用于与数据库进行交互。
当没有为模型类定义管理器时,Django会为每一个模型类生成一个名为objects的管理器,自定义管理器后,Django不再生成默认管理器objects。
为模型类BookInfo定义管理器books语法如下:
class BookInfo(models.Model):
...
books = models.Manager()
管理器是Django的模型进行数据库操作的接口,Django应用的每个模型类都拥有至少一个管理器。Django支持自定义管理器类,继承自models.Manager。
自定义管理器类主要用于两种情况:
1.修改原始查询集,重写all()方法。
a)打开booktest/models.py文件,定义类BookInfoManager
#图书管理器
class BookInfoManager(models.Manager):
def all(self):
#默认查询未删除的图书信息
#调用父类的成员语法为:super().方法名
return super().all().filter(isDelete=False)
b)在模型类BookInfo中定义管理器
class BookInfo(models.Model):
...
books = BookInfoManager()
2.在管理器类中定义创建对象的方法
对模型类对应的数据表进行操作时,推荐将这些操作数据表的方法封装起来,放到模型管理器类中。
a)打开booktest/models.py文件,定义方法create。
class BookInfoManager(models.Manager):
...
#创建模型类,接收参数为属性赋值
def create_book(self, title, pub_date):
#创建模型类对象self.model可以获得模型类
book = self.model()
book.btitle = title
book.bpub_date = pub_date
book.bread=0
book.bcommet=0
book.isDelete = False
# 将数据插入进数据表
book.save()
return book
b)为模型类BookInfo定义管理器books语法如下
class BookInfo(models.Model):
...
books = BookInfoManager()
c)调用语法如下:
调用:book=BookInfo.books.create_book("abc",date(1980,1,1))
在模型类中定义类Meta,用于设置元信息,如使用db_table自定义表的名字。
数据表的默认名称为:
<app_name>_<model_name>
例:
booktest_bookinfo
例:指定BookInfo模型类生成的数据表名为bookinfo。
在BookInfo模型类中添加如下内容,代码如下:
#定义图书模型类BookInfo
class BookInfo(models.Model):
...
#定义元选项
class Meta:
db_table='bookinfo' #指定BookInfo生成的数据表名为bookinfo
最后:
文章为18年python全栈学习资料记录转载,侵告删