django框架model

来源:互联网 发布:tableview卡顿优化 编辑:程序博客网 时间:2024/06/03 19:25

模型model

配置mysql数据库

在setting.py中配置

创建mysql数据库 在setting.py文件中找到DATABASES项(默认使用SQLITE3)修改为使用mysql(数据库 数据库名 主机host 端口port  用户名 密码)    代码如下:        DATABASES = {            'default': {                'ENGINE': 'django.db.backends.mysql',                'NAME': 'test2',                'USER': 'root',                'PASSWORD': 'mysql',                'HOST': 'localhost',                'PORT': '3306',    }}

在init中安装

在init.py中引入pymysql包    import pymysql    pymysql.install_as_MySQLdb()

定义模型

定义模型类

模型类被定义在“应用/models.py”文件中,此例中为“booktest/models.py”文件 模型类必须继承自Model类,位于包django.db.models中

模型类的属性

属性objects:管理器,是Manager类型的对象,用于与数据库进行交互
当没有为模型类定义管理器时,Django会为模型类生成一个名为objects的管理器,自定义管理器后,Django不再生成默认管理器objects
为模型类BookInfo定义管理器books语法如下
class BookInfo(models.Model):    ...    books = models.Manager()

管理器Manager

管理器是Django的模型进行数据库操作的接口,Django应用的每个模型都拥有至少一个管理器
Django支持自定义管理器类,继承自models.Manager

自定义管理器类主要用于两种情况

1.修改原始查询集,重写get_queryset()方法
2.向管理器类中添加额外的方法,如创建对象

1.修改原始查询集,重写get_queryset()方法
打开booktest/models.py文件,定义类BookInfoManager
//图书管理器class BookInfoManager(models.Manager):        def get_queryset(self):            #默认查询未删除的图书信息            #调用父类的成员语法为:super(子类型, self).成员            return super(BookInfoManager, self).get_queryset().filter(isDelete=False)
在模型类BookInfo中定义管理器
class BookInfo(models.Model):        ...    books = BookInfoManager()
2.在管理器类中定义创建对象的方法
当创建模型类对象时,django不会对数据库进行读写操作,调用save()方法才与数据库交互,进行insert或update操作,将数据保存到数据库中
如果模型类的属性比较多,逐个属性赋值很麻烦,推荐使用管理器方式
打开booktest/models.py文件,定义方法create
class BookInfoManager(models.Manager):    ...    #创建模型类,接收参数为属性赋值    def create(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        return book
为模型类BookInfo定义管理器books语法如下
class BookInfo(models.Model):...books = BookInfoManager()

定义属性

属性 = model.字段类型(选项)例: btitle = models.CharField(max_length=20)#图书名称

字段类型

四种常用:整数 字符 布尔 日期

关系字段类型

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

选项(通过选项实现对字段的约束)

null:如果为True,表示允许为空,默认值是Falseblank:如果为True,则该字段允许为空白,默认值是False对比:null是数据库范畴的概念,blank是表单验证证范畴的db_column:字段的名称,如果未指定,则使用属性的名称db_index:若值为True, 则在表中会为此字段创建索引,默认值是Falsedefault:默认值primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用unique:如果为True, 这个字段在表中必须有唯一值,默认值是False

元选项(数据表的默认名称)

<app_name>_<model_name>例: booktest_bookinfo在模型类中定义类Meta,用于设置元信息,如使用db_table自定义表的名字

迁移

将数据库模型同步到Django项目的数据库中 建立对应的表来反应创建的model模型
生成迁移:    python manage.py makemigrations执行迁移:    python manage.py migrate

数据操作

增加

str: 在将对象转换成字符串时会被调用

修改

save(): 将模型对象保存到数据表中

删除

delete():将模型对象从数据表中删除

查询集

两大特性

惰性执行(调用时访问数据库)缓存(查询结果被缓存下来、下次查询使用之前缓存数据)

返回过滤器

返回列表的过滤器如下:
all():返回所有数据filter():返回满足条件的数据exclude():返回满足条件之外的数据,相当于sql语句中where部分的not关键字order_by():排序
返回单个值的过滤器如下:
get():返回单个满足条件的对象如果未找到会引发"模型类.DoesNotExist"异常如果多条被返回,会引发"模型类.MultipleObjectsReturned"异常count():返回当前查询的总条数aggregate():聚合exists():判断查询集中是否有数据,如果有则返回True,没有则返回False

例 :查询所有,编辑booktest/views.py的index视图,运行查看

 list = BookInfo.books.all()

查询

实现sql中where的功能,调用过滤器filter()、exclude()、get()属性名称__比较运算符=值   

基本查询

exact:表示判等
例:查询编号为1的图书list=BookInfo.books.filter(id__exact=1)可简写为:list=BookInfo.books.filter(id=1)不等于使用等于的运算符,使用exclude()过滤器例:查询编号不等于3的图书list = BookInfo.books.exclude(id=3)
contains:是否包含
说明:如果要包含%无需转义,直接写即可例:查询书名包含‘传’的图书list=BookInfo.books.filter(btitle__contains='传'
startswith、endswith:以指定值开头或结尾
例:查询书名以‘部’结尾的图书list=BookInfo.books.filter(btitle__endswith='部')
isnull:是否为null
例:查询书名不为空的图书list = BookInfo.books.filter(btitle__isnull=False)
in:是否包含在范围内
例:查询编号为1或3或5的图书list = BookInfo.books.filter(pk__in=[1, 3, 5])
gt、gte、lt、lte:大于、大于等于、小于、小于等于不等于
查询编号大于3的图书list = BookInfo.books.filter(id__gt=3)
year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算
例:查询1980年发表的图书list=BookInfo.books.filter(bpub_date__year=1980)
F对象(属性比较)
语法如下  F(属性名)例:查询阅读量大于等于评论量的图书from django.db.models import F...list = BookInfo.books.filter(bread__gte=F('bcommet'))可以在F()对象上使用算数运算例:查询阅读量大于2倍评论量的图书list = BookInfo.books.filter(bread__gt=F('bcommet') * 2)
Q对象(多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字)
例:查询阅读量大于20,并且编号小于3的图书list=BookInfo.books.filter(bread__gt=20,id__lt=3)或list=BookInfo.books.filter(bread__gt=20).filter(id__lt=3)
如果需要实现逻辑或or的查询,需要使用Q()对象结合|运算符
Q对象被义在django.db.models中语法:Q(属性名__运算符=值)例:查询阅读量大于20的图书,改写为Q对象如下from django.db.models import Q...list = BookInfo.books.filter(Q(bread__gt=20))
Q对象可以使用&、|连接,&表示逻辑与,|表示逻辑或
例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现list = BookInfo.books.filter(Q(bread__gt=20) | Q(pk__lt=3))
Q对象前可以使用~操作符,表示非not
例:查询编号不等于3的图书list = BookInfo.books.filter(~Q(pk=3))

关联查询(类似join查询)

关联模型类名小写__属性名__运算符=值
如果没有没有“__运算符”部分,表示等于,结果和sql中的inner join相同
例:查询图书,要求图书中英雄的描述包含‘八’list = BookInfo.books.filter(heroinfo__hcontent__contains='八')例:查询书名为“天龙八部”的所有英雄list = HeroInfo.objects.filter(hbook__btitle='天龙八部')

聚合查询

使用aggregate()过滤器调用聚合函数
聚合函数包括:Avg,Count,Max,Min,Sum,被定义在django.db.models中
例:查询图书的总阅读量from django.db.models import Sum...list = BookInfo.books.aggregate(Sum('bread'))使用count时一般不使用aggregate()过滤器

例:查询图书总数
list = BookInfo.books.count()

关联对象

在定义模型类时,可以指定三种关联关系,最常用的是一对多关系,如本例中的“图书-英雄”就为一对多关系,接下来进入shell练习关系的查询
python manage.py shell查询编号为1的图书book=BookInfo.books.get(pk=1)获得book图书的所有英雄book.heroinfo_set.all()获得编号为1的英雄hero=HeroInfo.objects.get(pk=1)获得hero英雄出自的图书hero.hbook

自关联

对于地区信息、分类信息等数据,表结构非常类似,每个表的数据量十分有限,为了充分利用数据表的大量数据存储功能,可以可以设计成一张表,内部的关系字段指向本表的主键,这就是自关联的表结构
打开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 makemigrationspython manage.py migrate

打开mysql命令行,导入数据

source areas.sql

打开booktest/views.py文件,定义视图area

from models import AreaInfo...//查询广州市的信息def area(request):    area = AreaInfo.objects.get(pk=440100)    return render(request, 'booktest/area.html', {'area': area})

打开booktest/urls.py文件,新建一条url

urlpatterns = [    ...    url(r'^area/$', views.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>
原创粉丝点击