Django---model基础(单表)
ORM
一、映射关系:
表名<--------------->类名
字段<-------------->属性
表记录<----------->类实例对象
创建表(建立表模型)
二、单表
- class Book(models.Model):
- nid = models.AutoField(primary_key=True)
- title = models.CharField(max_length=32)
- authors = models.CharField(max_length=32)
- publishDate = models.DateField()
- price = models.DecimalField(max_digits=5, decimal_places=2)
1.通过logging可以查看翻译成的sql语句
- LOGGING = {
- 'version': 1,
- 'disable_existing_loggers': False,
- 'handlers': {
- 'console':{
- 'level':'DEBUG',
- 'class':'logging.StreamHandler',
- },
- },
- 'loggers': {
- 'django.db.backends': {
- 'handlers': ['console'],
- 'propagate': True,
- 'level':'DEBUG',
- },
- }
- }
- 1、models.AutoField 自增列= int(11)
- 如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
- 2、models.CharField 字符串字段
- 必须 max_length 参数
- 3、models.BooleanField 布尔类型=tinyint(1)
- 不能为空,Blank=True
- 4、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar
- 继承CharField,所以必须 max_lenght 参数
- 5、models.DateField 日期类型 date
- 对于参数,auto_now =True则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
- 6、models.DateTimeField 日期类型 datetime
- 同DateField的参数
- 7、models.Decimal 十进制小数类型= decimal
- 必须指定整数位max_digits和小数位decimal_places
- 8、models.EmailField 字符串类型(正则表达式邮箱)=varchar
- 对字符串进行正则表达式
- 9、models.FloatField 浮点类型= double
10、models.IntegerField 整形- 11、models.BigIntegerField 长整形
- integer_field_ranges ={
- 'SmallIntegerField':(-32768,32767),
- 'IntegerField':(-2147483648,2147483647),
- 'BigIntegerField':(-9223372036854775808,9223372036854775807),
- 'PositiveSmallIntegerField':(0,32767),
- 'PositiveIntegerField':(0,2147483647),
- }
- 12、models.IPAddressField 字符串类型(ip4正则表达式)
- 13、models.GenericIPAddressField 字符串类型(ip4和ip6是可选的)
- 参数protocol可以是:both、ipv4、ipv6
- 验证时,会根据设置报错
- 14、models.NullBooleanField 允许为空的布尔类型
- 15、models.PositiveIntegerFiel 正Integer
- 16、models.PositiveSmallIntegerField 正smallInteger
- 17、models.SlugField 减号、下划线、字母、数字
- 18、models.SmallIntegerField 数字
- 数据库中的字段有:tinyint、smallint、int、bigint
- 19、models.TextField 字符串=longtext
- 20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]]
- 21、models.URLField 字符串,地址正则表达式
- 22、models.BinaryField 二进制
- 23、models.ImageField图片
- 24、models.FilePathField文件
添加表记录
三、
1.添加表记录(save和create)
方式一:book_obj=models.Book(title=title)
book_obj.save() #将数据保存到数据库
方式二:book_obj=models.Book.objects.create(title=title)
2.查询
- 1.all 查询所有结果 用法:models.表名.objects.all() 结果是QuerySet集合 [model对象]
- 2.filter 查询所给筛选匹配的对象 用法:models.表名.objects.filter() 结果是:QuerySet集合 如:ret=models.表名.objects.filter(auther='mqj',price=123)
- 3.get 查询所给筛选匹配的对象,返回值只有一个,如果筛选的对象超过一个或没有就会报错 用法:models.表名.objects.get() 结果是:model对象 如:ret=models.表名.objects.get(auther="yuan")
- 4.exclude 包含筛选条件你匹配的对象 用法:ret=models.表名.objects.exclude
- (author="yuan")
- 5.values 方法 返回的是列表中一个一个的可迭代字典 返回的是列表中一个一个的可迭代字典 用法:ret=models.表名.objects.filter(author="yuan").value("title","price")
- 6.values_list 方法 返回的是列表中一个一个的元组序列 用法:ret=models.表名.objects.filter(author="yuan").value_list("title","price")
- 7.reverse():对查询的结果反向排序
- 8.order_by():对查询的结果排序
- 9.ddistinct(): 返回的结果中剔除重复记录
- 10.count(): 返回数据库匹配查询数量 用法:ret=models.Book.objects.filter(author="yuan").count()
- 11.first(): 返回第一条记录 用法:ret = models.Book.objects.all().first()
- 12.last(): 返回最后一条记录 用法:ret = models.Book.objects.all().last()
- 13.exists(): 返回True或False 用法:ret=models.Book.objects.all().existst()
3、双下划线之单表查询:
- models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值
- models.Tb1.objects.filter(id__in=[11,22,33]) # 获取id等于11、22、33的数据
- models.Tb1.objects.filter(name__contains="ven")
- models.Tb1.objects.filter(name__icontains="ven")
- models.Tb1.obiects.filter(id__range=[1,2]) #范围bettwen and
- startswith,istartswith,endswith,iendswith
4.修改
- 修改方式1:save(效率低)
- 如: book_obj=models.Book.objects.filter(nid=id)[0]
- book_obj.title="金平"
- book_obj.save()
- 修改方式2:
- title=request.POST.get("title")
- authors=request.POST.get("authors")
- pubDate=request.POST.get("pubDate")
- price=request.POST.get("price")
- models.Book.objects.filter(nid=id).update(title=title,authors=authors,publishDate=pubDate,price=price)
5.删除:
delect
- 了不起的双下划线:
- models.表名.objects.filter(id__gt=10)
- models.表名.objects.filter(title__startswith="py")
- models.Tb1.objects.filter(id__range=[1, 2])
- models.Tb1.objects.filter(id__in=[11, 22, 33])
四、表关联操作
实例:我们来假定下面这些概念,字段和关系
作者模型:一个作者有姓名和年龄。
作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)
出版商模型:出版商有名称,所在城市以及email。
书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)。
- class Book(models.Model):
- nid = models.AutoField(primary_key=True)
- title = models.CharField(max_length=32)
- publishDate = models.DateField()
- price = models.DecimalField(max_digits=5, decimal_places=2)
- publish = models.ForeignKey("Publish", related_name="bookList")
- authorlist = models.ManyToManyField("Author", related_name="bookList")
- def __str__(self):
- return self.title
- class Publish(models.Model):
- name = models.CharField(max_length=32)
- addr = models.CharField(max_length=32)
- def __str__(self):
- return self.name
- class Author(models.Model):
- name = models.CharField(max_length=32)
- age = models.IntegerField()
- def __str__(self):
- return self.name
- class AuthorDetail(models.Model):
- tel=models.IntegerField()
- addr=models.CharField(max_length=32)
- author=models.OneToOneField("Author",related_name="authorList")
表关系:
1.一对多
2.一对一
3.多对多
- 添加记录:
- 一对多:
- 创建一对多:
- publish=models.ForeignKey("Publish",related_name="bookList")
- 添加记录方式1:
- models.Book.objects.create(publish_id=1)
- 添加记录方式2:
- pubObj=models.Publish.objects.filter(name="人民出版社")[0]
- models.Book.objects.create(publish=pubObj) # 关联的出版社对象
- 多对多:
- 创建多对多关系:
- authorlist=models.ManyToManyField("Author",related_name="bookList")
- 多对多添加记录:
- book_obj=models.Book.objects.create(title="追风筝的人", price=100, publishDate="2017-12-12", publish_id=2)
- alex_obj=models.Author.objects.filter(name="alex")[0]
- egon_obj=models.Author.objects.filter(name="egon")[0]
- book_obj.authorlist.add(alex_obj,egon_obj)
- 查询记录:
- 正向查询:
- 一对多:
- linux_obj=models.Book.objects.filter(title="linux").first()
- print(linux_obj.publish.name) # 与这本书对象关联的出版社对象的名字
- 多对多:
- linux_obj=models.Book.objects.filter(title="linux").first()
- print(linux_obj.authorlist.all()) # 与这本书关联的所有作者对象集合
- 反向查询:
- #一对多的反向查询:
- eg:人民出版社出版过的书籍的名字
- publish_obj=models.Publish.objects.filter(name="人民出版社")[0]
- print(publish_obj.bookList.all()) # 与该年出版社关联的所有书籍对象的集合
- #多对多的反向查询:
- 查询yuan出版过的所有书籍的名字和价格:
- author_yuan=models.Author.objects.get(name="yuan")
- print(author_yuan.bookList.all()) # 与该作者关联的所有书籍书籍对象的集合
2.基于对象的查询
- 基于对象关联查询:
- if 一对多查询(Book--Publish):
- 正向查询,按字段:
- book_obj.publish : 与这本书关联的出版社对象 book_obj.publish.addr: 与这本书关联的出版社的地址
- 反向查询,按表名_set
- publish_obj.book_set: 与这个出版社关联的书籍对象集合 publish_obj.book_set.all() :[obj1,obj2,....]
- if 一对一查询(Author---AuthorDetail):
- 正向查询,按字段:
- author_obj.ad : 与这个作者关联的作者详细信息对象
- 反向查询:按表名:
- author_detail_obj.author : 与这个作者详细对象关联的作者对象
- if 多对多(Book----Author):
- 正向查询,按字段:
- book_obj.authorList.all(): 与这本书关联的所有这作者对象的集合 [obj1,obj2,....]
- 反向查询,按表名_set:
- author_obj.book_set.all() : 与这个作者关联的所有书籍对象的集合
3.双下划线的跨表查询
- 查询python这本书出版社的地址
- # 方式一:
- # book_obj=models.Book.objects.filter(title="python").first()
- # print(book_obj.publish.name)
- # 方式二(双下划线):
- # book_obj=models.Book.objects.filter(title="python").values("publish__addr")
- # print(book_obj)
- # 方式三(双下划线):
- # book_obj=models.Publish.objects.filter(bookList__title="python").values("addr")
- # print(book_obj)
- 查询老男孩出版社出版过的所有书籍的名字与价格
- # 方式一:
- # book_obj=models.Publish.objects.filter(name="老男孩出版社").first()
- # print(book_obj.bookList.all().values("title","price"))
- # 方式二:(双下划线)
- # book_obj=models.Publish.objects.filter(name="老男孩出版社").values("bookList__title","bookList__price")
- # print(book_obj)
- # 方式三(双下划线):
- # book_obj=models.Book.objects.filter(publish__name="老男孩出版社").values("title","price")
- # print(book_obj)
- # egon出版过的所有书籍名称以及出版社名称
- # book_obj=models.Author.objects.filter(name="egon").values("bookList__title","bookList__authorlist__name")
- # print("book_obj",book_obj)
- 查询egon出过的所有书籍的名字(多对多)
- book_obj=models.Author.objects.filter(name="egon").values("bookList__title")
- print(book_obj)
- book_obj=models.Book.objects.filter(authorlist__name="egon").values("title")
- print(book_obj)
- 手机号以151开头的作者出版过的所有书籍名称以及出版社名称
- # book_obj=models.AuthorDetail.objects.filter(tel__startswith="151").first()
- # print(book_obj.author.bookList.all().values("title","publish__name"))
- # 方法2
- # models.Book.objects.filter(authorlist__author_detail__tel__startswith="151").values("title", "publish__name")
- if 一对多查询(Book--Publish):
- 正向查询,按字段:
- # 查询linux这本书的出版社的名字:
- models.Book.objects.all().filter(title="linux").values("publish__name")
- 反向查询:按表名:
- # 查询人民出版社出版过的所有书籍的名字
- models.Publish.objects.filter(name="人民出版社出版").values("book__title")
- if 一对一查询(Author---AuthorDetail):
- 正向查询,按字段:
- models.Author.objects.filter(name="egon).values("ad__tel")
- 反向查询:按表名:
- models.AuthorDetail.objects.filter(tel="").values("author__name")
- if 多对多(Book----Author):
- 正向查询,按字段:
- models.Book.objects.filter(title="python").values("authorList__name") [{},{},{},{}]
- 正向查询,按表名:
- models.Author.objects.filter(name="alex").values("book__price")
- 注意:
- publish=models.ForeignKey("Publish",related_name="bookList")
- authorlist=models.ManyToManyField("Author",related_name="bookList")
- ad=models.models.OneToOneField("AuthorDetail",related_name="authorInfo")
- 反向查询的时候都用:related_name
4.查询
- 一对多的查询
- # 查询linux这本书的出版社的地址?
- #linux_obj=models.Book.objects.filter(title="linux").first()
- #
- # print(linux_obj.title)
- # print(linux_obj.price)
- # print(linux_obj.publishDate)
- #
- # print(linux_obj.publish.name) # 与这本书对象关联的出版社对象
- #print(linux_obj.publish.addr) # 与这本书对象关联的出版社对象
- # 人民出版社出版过的书籍的名字
- # publish_obj=models.Publish.objects.filter(name="人民出版社")[0]
- # print(publish_obj.bookList.all()) # 与这个出版社对象关联的所有书籍对象
- 多对多的查询
- # 查询追风筝的人的所有作者的姓名和年龄
- # book_obj=models.Book.objects.filter(title="追风筝的人")[0]
- # print("=====",book_obj.authorlist.all() ) # 与这本书关联的所有作者对象,集合对象
- # authorlist=book_obj.authorlist.all()
- # print(authorlist.values("name","age"))
- # 查询yuan出版过的所有书籍的名字和价格
- #author_yuan=models.Author.objects.get(name="yuan")
- #print(author_yuan.book_set.all()) # 与这个作者关联的所有书籍对象
- #print(author_yuan.bookList.all().values("title","price"))
- 一对一关系查询
- 正向查询
- #查询手机号为456的作者的姓名
- # ad=models.AuthorDetail.objects.filter(tel="456").first()
- # print(ad.author.name)
- #detail_obj=models.AuthorDetail.objects.filter(tel="456").first()
- # print(detail_obj.author.name)# 与tel="456"的Author2Detail关联的作者对象
- #
- 反向查询
- # 查询景丽洋的手机号
- # author_obj=models.AuthorA.objects.filter(name="景丽洋").first()
- # print(author_obj.author2detail.tel) # 789
- # print(author_obj.abc.tel) # 789
5.添加
- 一对多的添加
- # 方式1
- #models.Book.objects.create(title="python",price=100,publishDate="2017-12-12",publish_id=1)
- # 方式2
- # pubObj=models.Publish.objects.filter(name="人民出版社")[0]
- # models.Book.objects.create(title="python2",price=120,publishDate="2017-10-12",publish=pubObj) # 关联的出版社对象
- 多对多的添加
- #book_obj=models.Book.objects.create(title="红楼梦", price=100, publishDate="2017-12-12", publish_id=2)
- # alex_obj=models.Author.objects.filter(name="alex")[0]
- # egon_obj=models.Author.objects.filter(name="egon")[0]
- # egon_obj=models.Author.objects.filter(name="yuan")[0]
- # print("======",book_obj.authorlist) # []
- # authorList=models.Author.objects.all()
- 绑定多对多的关系
- # #book_obj.authorlist.add(alex_obj,egon_obj) # [alex_obj,egon_obj]
- # book_obj.authorlist.add(*authorList) # [alex_obj,egon_obj]
- 解除多对多的关系
- # book_obj=models.Book.objects.filter(title="红楼梦").first()
- # authorList=models.Author.objects.filter(id__lt=3)
- # print(book_obj.authorlist.remove(*authorList))
- 清除关系方法
- # book_obj = models.Book.objects.filter(title="红楼梦").first()
- # book_obj.authorlist.clear()
五、聚合函数
- from django.db.models import Avg,Sum,Count,Max,Min
- 聚合函数:aggregate
- # 查询所有图书的价格和
- ret=models.Book.objects.all().aggregate(priceSum=Sum("price"))
- ret=models.Book.objects.all().aggregate(priceAvg=Avg("price"),priceSum=Sum("price"))
- print(ret) # {'price__sum': Decimal('166.00')}
- 分组函数 annote函数
- # 查询每一本书的作者个数
- book_list=models.Book.objects.all().annotate(c=Count("authorlist__name"))
- for book_obj in book_list:
- print(book_obj.c)
- # 查询每一个出版社出版过的最便宜的书籍
- ret=models.Book.objects.all().annotate(Min("price"))
- print(ret)
统计不止一个作者的图书:
- queryResult=Book.objects
- .annotate(num_authors=Count('authors'))
- .filter(num_authors__gt=1)
- 查询各个作者出的书的总价格:
- # 按author表的所有字段 group by
- queryResult=Author.objects
.annotate(SumPrice=Sum("book__price"))
.values_list("name","SumPrice")- print(queryResult)
- #按authors__name group by
- queryResult2=Book.objects.values("authors__name")
.annotate(SumPrice=Sum("price"))
.values_list("authors__name","SumPrice")- print(queryResult2)
- 分组查询:
- querySet().annotate() --- 返回的是querySet
- #统计每一个出版社中最便宜的书籍的价格
- sql:
- select Min(price) from book group by publish_id;
- ORM:
- models.Book.objects.values("publish__name").annotate(Min("price"))
六、F查询与Q查询
F查询
1.查询评论数大于收藏数的书籍:
- from django.db.models import F
- Book.objects.filter(commnetNum__lt=F('keepNum'))
2. 查询评论数大于收藏数2倍的书籍
- Book.objects.filter(commnetNum__lt=F('keepNum')*2)
3.修改操作也可以使用F函数,比如将每一本书的价格提高30元:
- Book.objects.all().update(price=F("price")+30)
Q查询
filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q
from
django.db.models
import
Q
Q(title__startswith
=
'Py'
)
- bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon"))
你可以组合& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询:
- bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title")
查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。例如:
- bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),
- title__icontains="python"
- )
补充:
有关Django中的命令:
- 下载Django:pip3 install Django
- 创建一个djang project:django-admin.py startptoject 项目名称;
- 在目录下创建应用:python manage.py startapp blog;
- 启动Django项目:python manage.py runserver 端口;
- python manage.py syncdb
- 注意:Django 1.7.1 及以上的版本需要用以下命令
- python manage.py makemigrations
- python manage.py migrate
- '''
- python manage.py createsuperuser
- # 按照提示输入用户名和对应的密码就好了邮箱可以留空,用户名和密码必填
- # 修改 用户密码可以用:
- python manage.py changepassword username
- '''
- 注意:
- 对象可以调用自己的属性
Django---model基础(单表)的更多相关文章
- 数据库开发-Django ORM的单表查询
数据库开发-Django ORM的单表查询 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查询集 1>.查询集相关概述 查询会返回结果的集,它是django.db.mod ...
- Django——model基础
ORM 映射关系: 表名 <-------> 类名 字段 <-------> 属性 表记录 <------->类实例对象 创建表(建立模型) 实例:我们来假定下 ...
- Django模型层-单表操作
ORM介绍 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的 ...
- Django Model基础 ORM
ORM 对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的 ...
- Django Model基础操作
关于设计django model django为我们集成了ORM对数据库进行操作,我们只需要进行定义model,django就会自动为我们创建表,以及表之间的关联关系 创建好一个django项目-首先 ...
- Django框架之单表操作
一.添加表记录 对于单表有两种方式 # 添加数据的两种方式 # 方式一:实例化对象就是一条表记录 Frank_obj = models.Student(name ="海东",cou ...
- Django 模型层--单表
ORM 简介 MTV或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这可以大大的减少了开 ...
- Django day07 (二)单表操作
单表操作 -mysql数据库:settings里配置: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME ...
- python 之 Django框架(orm单表查询、orm多表查询、聚合查询、分组查询、F查询、 Q查询、事务、Django ORM执行原生SQL)
12.329 orm单表查询 import os if __name__ == '__main__': # 指定当前py脚本需要加载的Django项目配置信息 os.environ.setdefaul ...
- Django【第6篇】:Django之ORM单表操作(增删改查)
django之数据库表的单表查询 一.添加表记录 对于单表有两种方式 # 添加数据的两种方式 # 方式一:实例化对象就是一条表记录 Frank_obj = models.Student(name =& ...
随机推荐
- SharePoint解决方案及开发系列(2)-ECM
很多次跟客户做咨询及沟通的时候,客户都问SharePoint能做什么?是不是就是做文档管理?为什么要花那么多的钱没SharePoint?高大上? 我上家公司面试的时候,我的那个BOSS面试官有一个问题 ...
- Introduction to Mathematical Thinking - Week 4
否定的逻辑 应该思考符号背后表示的逻辑,而不是像操作算术运算符一样操作逻辑符号. 比如 对于任意的 x,x属于自然数,那么 x 是偶数或者奇数:这是对的 如果使用“乘法分配律”拆分,变成“对于任意的x ...
- WordArray (An array of 32-bit words.
CryptoJS中WordArray - qiqi715 - 博客园 http://www.cnblogs.com/qiqi715/p/9623421.html
- SQLServer与ASP中DATEDIFF函数区别
一.SQLServer: 格式: DATEDIFF(interval,startdate,enddate) interval参数: 年-yy,yyyy 季度-qq,q 月-mm,m 年中的日-dy,y ...
- 使用GUID作为数据表主键的好处(转)
http://blog.itpub.net/3875/viewspace-789520/ 分类: 数据库开发技术 使用GUID作为数据表主键的好处 [@more@] 使用GUID作为数据表主键的好处 ...
- PAT 1071. 小赌怡情(15) JAVA
1071. 小赌怡情(15) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 常言道“小赌怡情”.这是一个很简单的 ...
- windows 安装 python _ flask
1:首先安装python虚拟环境;(略) 2: 添加一个虚拟环境: 在你的项目目录里直接 virtualenv venv 启动虚拟环境;\venv\Scripts 直接运行activate 3: 在虚 ...
- List contents of directories in a tree-like format
Python programming practice. Usage: List contents of directories in a tree-like format. #!/usr/bin/p ...
- MyEclipse工具栏的隐藏与显示及自定义
Myeclipse的工具栏 1.隐藏 工具栏---->右键---->hide toolbar 2.显示 window ----> show toolbar 3.自定义 ...
- Loadrunder脚本篇——Run-time Settings之Preferences
打开Preferences设置对话框,这里提供了对运行时的参数选择设置 Enable Image and Text Check 开启图片和文本检查.允许用户在回放期间通过web_find(文本检测)或 ...