0、数据库配置

django默认支持sqlite,mysql, oracle,postgresql数据库。Django连接数据库默认编码使用UTF8,使用中文不需要特别设置。

  1. sqlite
  2. django默认使用sqlite的数据库,默认自带sqlite的数据库驱
  3. 引擎名称:django.db.backends.sqlite3
  4. mysql
  5. 引擎名称:django.db.backends.mysql

mysql引擎配置:

'defaults': {
  'ENGINE': 'django.db.backends.mysql',
  'NAME':'127.0.0.1',
  'USER':'root',
  'PASSWORD':'',
  }

mysql引擎底层驱动的py3支持问题:

  1. mysql驱动程序
  2. MySQLdb(mysql python),Django默认使用改驱动,但改驱动在python3下存在兼容性问题。因此使用PyMySQL
  3. PyMySQL(纯pythonmysql驱动程序)
  4. mysql驱动python3解决方法
  5. 找到项目名文件下的__init__,在里面写入:
  6. import pymysql
  7. pymysql.install_as_MySQLdb()

一、Model类定义

1、Model类创建

下面这个模型类将作为本篇博客的基础模型,所有的实例都基于此。

  1. from django.db import models
  2.  
  3. class Publisher(models.Model):
  4. name = models.CharField(max_length=30, verbose_name="名称")
  5. website = models.URLField()
  6. # book_set 反向关联一对多字段的Book
  7. def __unicode__(self):
  8. return self.name
  9.  
  10. class Author(models.Model):
  11. name = models.CharField(max_length=30)
  12. # authordetail 反向关联一对一字段AuthorDetail表
  13. # book_set 反向关联一对多字段的Book
  14. def __unicode__(self):
  15. return self.name
  16. class AuthorDetail(models.Model):
  17. sex = models.BooleanField(max_length=1, choices=((0, '男'),(1, '女'),))
  18. author = models.OneToOneField(Author)
  19. # author_id隐藏字段,正向关联一对一字段的Author对象的id
  20.  
  21. class Book(models.Model):
  22. title = models.CharField(max_length=100)
  23. authors = models.ManyToManyField(Author)
  24. publisher = models.ForeignKey(Publisher,null=True)
  25. # publisher_id隐藏字段,正向关联一对多字段的Publisher对象的id
  26. price=models.DecimalField(max_digits=5,decimal_places=2,default=10)
  27. def __unicode__(self):
  28. return self.title
  1. #coding:utf-
  2. from __future__ import unicode_literals
  3.  
  4. from django.db import models
  5.  
  6. class Publisher(models.Model):
  7. name = models.CharField(max_length=, verbose_name="名称")
  8. website = models.URLField()
  9. def __unicode__(self):
  10. return self.name
  11.  
  12. class Author(models.Model):
  13. name = models.CharField(max_length=)
  14. def __unicode__(self):
  15. return self.name
  16.  
  17. class AuthorDetail(models.Model):
  18. sex = models.BooleanField(max_length=, choices=((, '男'),(, '女'),))
  19. author = models.OneToOneField(Author)
  20.  
  21. class Book(models.Model):
  22. title = models.CharField(max_length=)
  23. authors = models.ManyToManyField(Author,through='Book2Author')
  24. publisher = models.ForeignKey(Publisher)
  25. price=models.DecimalField(max_digits=,decimal_places=,default=)
  26. def __unicode__(self):
  27. return self.title
  28.  
  29. class Book2Author(models.Model):
  30. book = models.ForeignKey(Book)
  31. author = models.ForeignKey(Author)
  32. groupname = models.CharField(max_length=)
  33.  
  34. #默认多对多关系Django自动为我们创建了一张中间表,仅提供3个字段,两个关联表的外键字段和一个id字段。
  35. #这种使用自定义中间表的方式,使得我们可以自定义的为中间表添加额外的字段。当我们需要为多对多关系提供额外字段时,用此方式。

自定义多对多中间表

2、同步数据库

模型表创建和更新的时候是要使用数据库迁移命令,使模型类的改变同步到数据库。

  1. makemigrations #创建变更记录
  2. migrate #同步到数据库

3、Model类(表)关系图:

名词说明:

  正向查询,从定义关系字段的类中去查询关系对象的值或值的集合。举个栗子:从AuthorDetail类中查询关联字段author对象的值。

  反向查询,从本类中查询被关联对象中的值或值的集合。举个栗子:从Author对象中查询被关联字段AuthorDetail对象的值。

4、字段类型:

  1. 1models.AutoField  自增列 = int(11)
  2.   如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True
  3. 2models.CharField  字符串字段
  4.   必须 max_length 参数
  5. 3models.BooleanField  布尔类型=tinyint(1)
  6.   不能为空,Blank=True
  7. 4models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
  8.   继承CharField,所以必须 max_lenght 参数
  9. 5models.DateField  日期类型 date
  10.   对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
  11. 6models.DateTimeField  日期类型 datetime
  12.   DateField的参数
  13. 7models.Decimal  十进制小数类型 = decimal
  14.   必须指定整数位max_digits和小数位decimal_places
  15. 8models.EmailField  字符串类型(正则表达式邮箱) =varchar
  16.   对字符串进行正则表达式
  17. 9models.FloatField  浮点类型 = double
  18. 10models.IntegerField  整形
  19. 11models.BigIntegerField  长整形
  20.   integer_field_ranges = {
  21.     'SmallIntegerField': (-32768, 32767),
  22.     'IntegerField': (-2147483648, 2147483647),
  23.     'BigIntegerField': (-9223372036854775808, 9223372036854775807),
  24.     'PositiveSmallIntegerField': (0, 32767),
  25.     'PositiveIntegerField': (0, 2147483647),
  26.   }
  27. 12models.IPAddressField  字符串类型(ip4正则表达式)
  28. 13models.GenericIPAddressField  字符串类型(ip4ip6是可选的)
  29.   参数protocol可以是:bothipv4ipv6
  30.   验证时,会根据设置报错
  31. 14models.NullBooleanField  允许为空的布尔类型
  32. 15models.PositiveIntegerFiel  正Integer
  33. 16models.PositiveSmallIntegerField  正smallInteger
  34. 17models.SlugField  减号、下划线、字母、数字
  35. 18models.SmallIntegerField  数字
  36.   数据库中的字段有:tinyintsmallintintbigint
  37. 19models.TextField  字符串=longtext
  38. 20models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
  39. 21models.URLField  字符串,地址正则表达式
  40. 22models.BinaryField  二进制
  41. 23models.ImageField 图片
  42. 24models.FilePathField 文件

ORM字段类型

5、字段选项:

  1. 1null=True
  2.   数据库中字段是否可以为空
  3. 2blank=True
  4.   django Admin 中添加数据时是否可允许空值
  5. 3primary_key = False
  6.   主键,对AutoField设置主键后,就会代替原来的自增 id
  7. 4auto_now auto_now_add
  8.   auto_now 自动创建---无论添加或修改,都是当前操作的时间
  9.   auto_now_add 自动创建---永远是创建时的时间
  10. 5choices 配置可选项
  11. GENDER_CHOICE = (
  12. (u'M', u'Male'),
  13. (u'F', u'Female'),
  14. )
  15. gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
  16. 6max_length 最大长度
  17. 7default  默认值
  18. 8verbose_name  Admin中字段的显示名称
  19. 9name|db_column  数据库中的字段名称
  20. 10unique=True  不允许重复
  21. 11db_index = True  数据库索引
  22. 12editable=True  在Admin里是否可编辑
  23. 13error_messages=None  错误提示
  24. 14auto_created=False  自动创建
  25. 15help_text  在Admin中提示帮助信息
  26. 16validators=[] 自定义数据格式验证
  27. 17upload-to 上传文件路径

字段选项

6、Model类的Meta(元数据)选项:

  1. abstract=False True就表示模型是抽象基类
  2. db_table = 'music_album' 自定义数库的表名称前缀
  3. get_latest_by = "datefield_name" 根据时间字段datefield_name排序,latest()和earliest()方法中使用的默认字段。
  4. db_tablespace 当前模型所使用的数据库表空间的名字。默认值是项目设置中的DEFAULT_TABLESPACE。如果后端并不支持表空间,这个选项可以忽略。
  5. ordering = ['-fieldname'] 对象默认的顺序,字段前面带有'-'符号表示逆序,否则正序。排序会增加查询额外开销。
  6. proxy = True 它作为另一个模型的子类,将会作为一个代理模型。
  7. unique_together 设置联合唯一。ManyToManyField不能包含在unique_together中。
  8. index_together 设置联合索引。
  9. index_together = [
  10. ["pub_date", "deadline"],
  11. ]
  12. 方便起见,处理单一字段的集合时index_together = ["pub_date", "deadline"]
  13.  
  14. verbose_name Admin里,个易于理解的表名称,为单数:verbose_name = "pizza"
  15. verbose_name_plural Admin里显示的表名称,为复数:verbose_name_plural = "stories",一般同verbose_name一同设置。

Meta元数据选项

二、对象CURD操作

2.1 基础对象CURD(无关联字段)

1、增

  1. 方法一:
  2. author= Author(name="鲁迅")
  3. author.save()
  4.  
  5. 方法二
  6. 创建对象并同时保存对象的快捷方法,存在关系字段时无法用此方法创建。
  7. create(**kwargs)
  8. Author.objects.create(name=u"鲁迅")
  9.  
  10. 方法三:
  11. 批量创建
  12. bulk_create(objs, batch_size=None) ret=Blog.objects.bulk_create([ Author(name="徐志摩"), Author(name="李白")])
  13.  
  14. 方法四:
  15. 存在就获取,不存在就创建
  16. get_or_create(defaults=None,**kwargs),
  17. defaults必须为一个字典,在创建时生效的默认值;**kwargs为查询条件。
  18. 创建对象时,使用**kwargsdefaults共同作用,取交集,defaults优先。
  19.  
  20. updated_values={"name":u"美猴王"}
  21. a、存在就获取,查询到结果多余一个出错MultipleObjectsReturned
  22. ret=Author.objects.get_or_create(name=u'徐志摩',defaults=updated_values)
  23. ret:(<Author: 徐志摩>, False)
  24. b、不存在就创建
  25. ret=Author.objects.get_or_create(name=u'徐志摩',defaults=updated_values)
  26. ret:(<Author: 美猴王>, True)
  27.  
  28. 方法五:
  29. 存在就更新,不存在就创建
  30. update_or_create(defaults=None, **kwargs)
  31. a、存在就更新
  32. updated_values={"name":u"猴王"}
  33. ret=Author.objects.update_or_create(defaults=updated_values,name=u"猴子")
  34. ret:(<Author: 猴王>, False)
  35. 根据给出的查询条件name=u"猴子"查找对象,查询到结果就使用defaults字典去更新对象。
  36.  
  37. b、不存在就创建
  38. ret=Author.objects.update_or_create(defaults=updated_values,name=u"猴子1")
  39. ret:(<Author: 猴王>, True)
  40. defaults必须为一个字典,在创建时生效的默认值;**kwargs为查询条件。
  41. 创建对象时,使用**kwargsdefaults共同作用,取交集,defaults优先。
  1. 2、删
  1. 使用delete会查找出相关表中的有关联的数据行一并删除
  2. 方法一
  3. Author.objects.filter(name="徐志摩").delete()
  4. (1, {u'otest.Book_authors': 0, u'otest.AuthorDetail': 0, u'otest.Author': 1})
  5. 方法二:
  6. a9=Author.objects.get(name="鲁迅")
  7. a9.delete()
  1. 3、改
  1. 方法一:
  2. update(**kwargs)返回更新的行数,批量修改
  3. ret=Author.objects.filter(name='秋雨').update(name="陶渊明")
  4.  
  5. 方法二:
  6. 单条修改
  7. a7=Author.objects.get(name="清风")
  8. a7.name=u"宋清风"
  9. a7.save()
  1. 4、查
    a、查询结果非QuertSet
  1. get(**kwargs)
  2. 在使用 get() 时,如果符合筛选条件的对象超过一个,就会抛出 MultipleObjectsReturned 异常。
  3. 在使用 get() 时,如果没有找到符合筛选条件的对象,就会抛出 DoesNotExist 异常。
  4. from django.core.exceptions import ObjectDoesNotExist
  5. try:
  6. e = Entry.objects.get(id=3)
  7. b = Blog.objects.get(id=1)
  8. except ObjectDoesNotExist:
  9. print("Either the entry or blog doesn't exist.")
  10.  
  11. in_bulk(id_list)
  12. 接收一个主键值列表,然后根据每个主键值所其对应的对象,返回一个主键值与对象的映射字典。
  13. Author.objects.in_bulk([1,2,3])
  14. {1: <Author: 苍松>, 2: <Author: 猴王>, 3: <Author: 宋清风>}
  15.  
  16. first() 查询第一条,一般使用前先排序,或者确定其只有一条数据。
  17. last() 查询最后一条,同上
  18.  
  19. count() 返回数据库中匹配查询(QuerySet)的对象数量。 count() 不会抛出任何异常。
  20.  
  21. exists() 如果 QuerySet 包含有数据,就返回 True 否则就返回 False。这可能是最快最简单的查询方法了。
  22.  
  23. latest(field_name=None) ,根据时间字段 field_name 得到最新的对象。
  24. earliest(field_name=None), 根据时间字段 field_name 得到最老的对象。
  1. #F使用查询条件的值,进行数值计算
  2.  
  3. from django.db.models import F
  4. Book.objects.filter(id=1).update(price=F('price')+10)

b、查询结果为QuerySet

 常用方法:

  1. 1filter(**kwargs)
  2. 过滤,返回一个新的QuerySet,包含与给定的查询参数匹配的对象。
  3. >>>q=Author.objects.filter(name=u"苍松")
  4. >>> q
  5. [<Author: 苍松>]
  6.  
  7. 2exclude(**kwargs)
  8. 反过滤,返回一个新的QuerySet,它包含不满足给定的查找参数的对象。功能与filter相反。
  9.  
  10. 3values(*fields)
  11. 返回一个新的QuerySet,但迭代时返回字典而不是模型实例对象。
  12. *fields表示需要取哪些字段,空表示取所有字段。
  13. >>> q=Author.objects.values("id")
  14. >>> q
  15. [{'id': 1}, {'id': 2}, {'id': 3}, {'id': 4}, {'id': 18}, {'id': 22}, {'id': 24}]
  16.  
  17. 4values_list(*fields, flat=False)
  18. 返回一个新的QuerySet,但迭代时返回元组而不是模型实例对象。
  19. *fields表示需要取哪些字段,空表示取所有字段。flat=True表示返回的结果为单个值而不是元组,多个字段时不能使用flat
  20. >>> q=Author.objects.values_list("id")
  21. >>> q
  22. [(1,), (2,), (3,), (4,), (18,), (22,), (24,)]
  23. >>> q=Author.objects.values_list("id",flat=True)
  24. >>> q
  25. [1, 2, 3, 4, 18, 22, 24]
  26.  
  27. 5all()
  28. 返回当前 QuerySet所有对象。
  29.  
  30. 6select_related(*field)
  31. 返回一个QuerySet,使用JOIN语句连表查询。它会在执行查询时自动跟踪外键关系,一次读取所有外键关联的字段,并尽可能地深入遍历外键连接,以减少数据库的查询。但数据关系链复杂的查询需要慎用。仅对外键生效。
  32.  
  33. 7prefetch_related(*field)
  34. prefetch_related()的解决方法是,分别查询每个表,然后用Python处理他们之间的关系。外键和多对多都生效。
  35.  
  36. 8order_by(*fields)
  37. 排序,返回一个新的QuerySet,隐式的是升序排序,-name表示根据name降序
  38. >>> q=Author.objects.order_by("name")
  39. >>> q
  40. [<Author: au>, <Author: 宋清风>, <Author: 猴王>, <Author: 美猴王>, <Author: 苍松>, <Author: 赵清风>, <Author: 陶渊明>]
  41. >>> q=Author.objects.order_by("-name")
  42. >>> q
  43. [<Author: 陶渊明>, <Author: 赵清风>, <Author: 苍松>, <Author: 美猴王>, <Author: 猴王>, <Author: 宋清风>, <Author: au>]
  44.  
  45. 9reverse()
  46. reverse()方法返回反向排序的QuerySet
  47. 必须对一个已经排序过的queryset(也就是q.ordered=True)执行reverse()才有效果。
  48.  
  49. 10distinct([*fields])
  50. 去重复。返回一个在SQL 查询中使用SELECT DISTINCT 的新QuerySet
  1. 1dates(field, kind, order='ASC')
  2. field 是你的 model 中的 DateField 字段名称。
  3. kind year”, month day 之一。 每个 datetime.date对象都会根据所给的 type 进行截减。
  4. year 返回所有时间值中非重复的年分列表。
  5. month 返回所有时间值中非重复的年/月列表。
  6. day 返回所有时间值中非重复的年/月/日列表。
  7. order, 默认是 ASC’,只有两个取值 ASC DESC’。它决定结果如何排序。
  8.  
  9. 2datetimes(field, kind, order=’ASC’)
  10. 返回一个 DateTimeQuerySet,参数与dates类似,多了"hour", "minute" ,"second"
  11.  
  12. 3none()
  13. 返回一个 EmptyQuerySet,它是一个运行时只返回空列表的 QuerySet。它经常用在这种场合:你要返回一个空列表,但是调用者却需要接收一个 QuerySet 对象。
  14.  
  15. 4defer(*fields)
  16. 将不想载入的字段的名称传给 defer() 方法,就可以做到延后载入。
  17. 在某些数据复杂的环境下,你的 model 可能包含非常多的字段,可能某些字段包含非常多的数据(比如,文档字段),或者将其转化为Python对象会消耗非常多的资源。在这种情况下,有时你可能并不需要这种字段的信息,那么你可以让 Django 不读取它们的数据。
  18.  
  19. 5only(*fields)
  20. only() 方法或多或少与 defer() 的作用相反。如果你在提取数据时希望某个字段不应该被延后载入,而应该立即载入,那么你就可以做使用 only()方法。
  21.  
  22. 6、多数据库切换using(alias)
  23. 单独使用无意义,配合其他查询集方法一起使用。
  24. Author.objects.using('backup')
  25.  
  26. 7、表锁定select_for_update(nowait=False)
  27. 单独使用无意义,配合其他查询集方法一起使用。
  28. 返回queryset,并将需要更新的行锁定,类似于SELECT FOR UPDATE的操作。
  29. entries = Entry.objects.select_for_update().filter(author=request.user)
  30. 所有匹配的entries都会被锁定直到此次事务结束。

其他方法

  1. 特别的:QuerySet可以使用切片限制查询集。
  1. 切片后依旧获得QuerySet,并且不会触发数据库查询。
  2. >>> a=Author.objects.all()[0:2]
  3. >>> type(a)
  4. <class 'django.db.models.query.QuerySet'>
  5.  
  6. 设置步长值后,获得到List类型值。触发数据库查询
  7. >>> a=Author.objects.all()[::2]
  8. >>> type(a)
  9. <type 'list'>
  10.  
  11. 使用索引,数据对象,触发数据库查询
  12. >>> Author.objects.all()[0]  #等价于Author.objects.all()[0:1].get()
    <Author: 苍松>
  1. 查看QuerySet的原始SQL语句
  1. 关于查看QuerySet的原始SQL语句,使用查询集的query对象。
  2. >>> q=Author.objects.all()
  3. >>> print q.query
  4. SELECT "otest_author"."id", "otest_author"."name" FROM "otest_author"

 c、查询条件(双下划线)

所有使用查询条件的查询和查询集过滤的方法(get,get_or_create,filter,exclude等)都可以使用双下划线组合出更复杂的查询条件。

另一种使用双下划线的情况就是跨表条件查询单情况,见下一节关联字段中跨表查询。

  1. 查询条件格式
  2. field__条件类型,例如a=Author.objects.get(id__exact=1)
  3. 默认为精确匹配
  4. 例如:Author.objects.get(id=1)等价于Author.objects.get(id__exact=1)
  5.  
  6. 一、精确匹配
  7. exact 精确匹配: Blog.objects.get(id__exact=1)
  8. iexact 忽略大小写的精确匹配,Blog.objects.filter(name__iexact='blog7')
  9. 二、模糊匹配
  10. (模糊匹配,仅PostgreSQL MySQL支持. SQLiteLIKE 语句不支持大小写敏感特性,因此模糊匹配对于 SQLite无法对大敏感)
  11. contains 大小写敏感的内容包含测试:Blog.objects.filter(name__contains='blog7')
  12. icontains 大小写不敏感的内容包含测试:
  13. startswith 大小写敏感的内容开头 Blog.objects.filter(name__startswith="blog")
  14. endswith 大小写敏感的内容结尾 endswith.
  15. istartswith 大小写不敏感的内容开头 startswith.
  16. iendswith 大小写不敏感的内容结尾 endswith.
  17.  
  18. 三、正则匹配
  19. regex
  20. 大小写敏感的正则表达式匹配。
  21. 它要求数据库支持正则表达式语法,而 SQLite 却没有内建正则表达式支持,因此 SQLite 的这个特性是由一个名为 REGEXP Python 方法实现的,所以要用到 Python 的正则库 re.
  22. Entry.objects.get(title__regex=r'^(An?|The) +')
  23. 等价于 SQL
  24. SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
  25. SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'c'); -- Oracle
  26. SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL
  27. SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite
  28.  
  29. iregex
  30. 忽略大小写的正则表达式匹配。
  31.  
  32. 四、范围匹配
  33. gt 大于: Blog.objects.filter(id__gt=3)
  34. gte 大于等于.
  35. lt 小于.
  36. lte 小于等于.
  37. ne 不等于.
  38. in 位于给定列表中: Blog.objects.filter(id__in=[1,3,5])
  39. range 范围测试: Blog.objects.filter(name__range=('blog1','blog5'))
  40.  
  41. 日期匹配:
  42. year date/datetime 字段, 进行精确的 匹配:Polls.objects.filter(pub_date__year=2005).
  43. month
  44. day
  45. hour
  46. minute
  47. second
  48.  
  49. 空值匹配
  50. isnull True/False; IF NULL/IF NOT NULL 查询:Blog.objects.filter(name__isnull=True)

d、 复杂查询条件,使用Q 对象进行复杂的查询

filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象。

  1. Q对象有两种使用方式,一种使用Tree模式。另一种是使用"|""&"符号进行与或操作。
  2.  
  3. Q构建搜索条件
  4. from django.db.models import Q
  5. con = Q()
  6.  
  7. q1 = Q()
  8. q1.connector = 'OR'
  9. q1.children.append(('id', 1))
  10. q1.children.append(('id', 2))
  11. #等价于Q(id=1) | Q(id=2)
  12.  
  13. q2 = Q()
  14. q2.connector = 'AND'
  15. q2.children.append(('id', 1))
  16. q2.children.append(('name__startswith', 'a'))
  17. #等价于Q(id=1) | Q(name__startswith='a')
  18.  
  19. con.add(q1, 'AND')
  20. con.add(q2, 'AND')
  21.  
  22. Q搜索可以和普通查询参数一起使用,但查询参数需要在最后。
  23. Author.objects.filter(q1,id=26)

2.2关联字段CURD操作(一对一,一对多,多对多表关系操作)

  1. 一对一和多对多的表关系的增删改查
  2. a1 = Author.objects.get(name="猴子")
  3. a2 = Author.objects.get(name="苍松")
  4. a3 = Author.objects.get(name="鲁迅")
  5. p1=Publisher.objects.get(name="机械出版社")
  6. p2=Publisher.objects.get(name="av")
  7.  
  8. ==============正向关系操作===================================================

  9. b1=Book(title="红楼梦",price=10)
  10. b1.publisher=p1或者b1.publisher_id=1 #一对多
  11. b1.save() 先保存book对象之后才能添加多对多关系
  12. b1.authors.add(a1,a2)或者b1.authors=[a1,a2] #多对多
  13. b1.save()
  14.  

  15. b1.publisher=None或者b1.publisher_id=None #一对多
  16. b1.authors.remove(a1,a2) 实际上是删除关系表otest_book_authors中的一条数据 #多对多
  17. b1.authors.clear() 清空所有关系 #多对多

  18. 查询
      Book.objects.filter(publisher__name=u"
    机械出版社")  #一对多,使用双下划线
      Book.objects.filter(authors__name=u"苍松")  #多对多,使用双下划线
  1. 获取字段值对象
  2. b2.publisher #一对多,对象下面的字段值继续使用.获取。例如b2.publisher.name
  3. b1.authors.all() #多对多
  4.  
  5. ==============反向关系操作===================================================

  6. p1.book_set.add(b1) #一对多,会更新现有的关系。(一个对象只能有一个外键)
  7. a3.book_set.add(b1) #多对多

  8. p1.book_set.remove(b1) #一对多
  9. a3.book_set.remove(b1) #多对多
  10. a3.book_set.clear() #多对多,清空所有关系

  11. 获取字段值对象
  12. a2.book_set.all() #多对多
  13. p1.book_set.all() #一对多
  14.  
  15. =============自定义中介模型方法===================================================
  16. 中介模型addcreate remove方法不可用。但是clear() 方法却是可用的,它可以清空某个实例所有的多对多关系。

三、使用原始SQL语句

Django提供两种方法使用原始SQL进行查询:一种是使用Manager.raw()方法,进行原始查询并返回模型实例;另一种直接执行自定义的SQL语句。

1、使用Manager.raw()方法

  1. Manager.raw(raw_query, params=None, translations=None)
  2. raw_query SQL查询语句。
  3. params 查询条件参数,是list或者dict
  4. translations 字段映射表,是一个dict
  5. Manager.raw()将查询结果映射到类字段,默认情况下映射到同名字段。返回结果是一个RawQuerySet
  1. 如果在其他的表中有一些Author数据,你可以很容易地把它们映射成Author实例。
  1. 手动指定字段映射字典。
  2. 方法一:使用AS,其他字段自动应设至Author表中的同名字段。
  3. na=Author.objects.raw("select name AS newname, id from otest_author")
  4. >>> na[]
  5. <Author_Deferred_name: 苍松>
  6. .
  7. 方法二:使用translations
  8. name_map={"name":"newname}
  9. na=Author.objects.raw("select * from otest_author",translations=name_map)
  10.  
  11. params参数防止SQL注入
  12. 方法一:使用list
  13. >>> na=Author.objects.raw("select * from otest_author where id =%s",[id])
  14. >>> na[]
  15. <Author: 苍松>
  16.  
  17. 方法二:使用dict
  18. 注意:SQLite后端不支持字典,你必须以列表的形式传递参数。
  19. 字典使用%(key)s占位符(key替换成字典中相应的key值)
  20. p_dict={"id":}
  21. na=Author.objects.raw("select * from otest_author where id =%(id)s",p_dict)

2.直接执行自定义的SQL

有时Manager.raw()方法并不十分好用,你不需要将查询结果映射成模型,或者你需要执行UPDATE、 INSERT以及DELETE查询。

  1. #单数据库
  2. from django.db import connection
  3. def my_custom_sql(self):
  4. cursor = connection.cursor()
  5. cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
  6. cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
  7. row = cursor.fetchone()
       connection.close()
  8. return row
  9.  
  10. #多数据库
  11. from django.db import connections
  12. cursor = connections['my_db_alias'].cursor()
  13. # Your code here...
  14.  
  15. 默认情况下,Python DB API会返回不带字段的结果,这意味着你得到的是一个列表,而不是一个字典。
  16. def dictfetchall(cursor):
  17. "Returns all rows from a cursor as a dict"
  18. desc = cursor.description
  19. return [
  20. dict(zip([col[] for col in desc], row))
  21. for row in cursor.fetchall()
  22. ]
  23.  
  24. >>> cursor.execute("SELECT id, parent_id FROM test LIMIT 2");
  25. >>> cursor.fetchall()
  26. ((54360982L, None), (54360880L, None))
  27.  
  28. >>> cursor.execute("SELECT id, parent_id FROM test LIMIT 2");
  29. >>> dictfetchall(cursor)
  30. [{'parent_id': None, 'id': 54360982L}, {'parent_id': None, 'id': 54360880L}]

四、分组和聚合

  1. Avg 平均值
  2. Count(expression, distinct=False 计算个数。如果distinct=TrueCount将只计算唯一的值。默认值为False
  3. Max 最大值
  4. Min 最小值
  5. Sum 求和
  1. 方法一:使用annotate方法,先分组(group by)再聚合
  2. from django.db.models import Count, Min, Max, Sum,Avg
  3. >>> Book.objects.values('publisher').annotate(counts_num=Count("*"))
  4. [{'publisher': 1, 'counts_num': 2}, {'publisher': 3, 'counts_num': 1}]
  5.  
  6. >>> Book.objects.values('publisher').annotate(Avg("price"))
  7. [{'publisher': 1, 'price__avg': 12.5}, {'publisher': 3, 'price__avg': 11.0}] #得到分组的多个值列表
  8. 使用values('publisher')进行group by分组后,在使用聚合函数才有意义。
  9. 默认聚合名称filedname__聚合函数名,作为聚合字段名。
  10.  
  11. 方法二:使用aggregate方法,先过滤再聚合
  12. Book.objects.filter(publisher_id=1).aggregate(Count("id"))
  13. {'id__count': 2} #得到单个值
  1. 参考文档:
      http://python.usyiyi.cn/django/index.html中文翻译1.8.2版中文不好的同学可以看这个 

Django之Model(一)--基础篇的更多相关文章

  1. Django学习笔记(基础篇)

    Django学习笔记(基础篇):http://www.cnblogs.com/wupeiqi/articles/5237704.html

  2. Django之Model操作进阶篇

    常用参数 null 数据库中字段是否可以为空 db_column 数据库中字段的列名 default 数据库中字段的默认值 primary_key 数据库中字段是否为主键 db_index 数据库中字 ...

  3. Python之路【第十六篇】:Django【基础篇】

    Python之路[第十六篇]:Django[基础篇]   Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了O ...

  4. 01: Django基础篇

    目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...

  5. Django 【基础篇】

    前戏 python Web程序 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env python #cod ...

  6. Python之路【第二十二篇】:Django之Model操作

    Django之Model操作   一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bi ...

  7. Django之Model组件

    Model组件在django基础篇就已经提到过了,本章介绍更多高级部分. 一.回顾 1.定义表(类) ##单表 from django.db import models class user(mode ...

  8. Django之模型层第一篇:单表操作

    Django之模型层第一篇:单表操作 一 ORM简介 ​ 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数 ...

  9. Django之模型层第二篇:多表操作

    Django之模型层第二篇:多表操作 一 表关系回顾 ​ 在讲解MySQL时,我们提到,把应用程序的所有数据都放在一张表里是极不合理的. ​ 比如我们开发一个员工管理系统,在数据库里只创建一张员工信息 ...

  10. DOM系列---基础篇

    DOM系列---基础篇   DOM (Document Object Model) 即文档对象模型, 针对 HTML 和 XML 文档的 API (应用程序接口) .DOM 描绘了一个层次化的节点树, ...

随机推荐

  1. [转]epoll技术

    在linux的网络编程中,很长的时间都在使用select来做事件触发.在linux新的内核中,有了一种替换它的机制,就是epoll. 相比于select,epoll最大的好处在于它不会随着监听fd数目 ...

  2. .NET中的Queue和Stack

    1.ArrayList类 ArrayList类主要用于对一个数组中的元素进行各种处理.在ArrayList中主要使用Add.Remove.RemoveAt.Insert四个方法对栈进行操作.Add方法 ...

  3. 怒刷DP之 HDU 1257

    最少拦截系统 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  4. System.Data.OracleClient requires Oracle client software version 8.1.7 or greater

    It is a security issue, so to fix it simply do the following: Go to the Oracle folder. 1- Right Clic ...

  5. 如果AlertView输入框为空,则禁止点击确定按钮

    //UIAlertView的代理方法(创建UIAlertView之后,copy此代理方法即可) - (BOOL)alertViewShouldEnableFirstOtherButton:(UIAle ...

  6. BZOJ 2456

    Description 给你一个n个数的数列,其中某个数出现了超过n div 2次即众数,请你找出那个数. Input 第1行一个正整数n.第2行n个正整数用空格隔开. Output 一行一个正整数表 ...

  7. C#的三大特性

    每个新手基本上都知道C#的三大特性,但是今天我给自己总结了一下这三大特性 1.封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中".在面向对象程序设计方法论中,封装是为 ...

  8. 【CSS3】---练习制作导航菜单

    练习题 根据所学知识,使用CSS3实现下图的导航菜单效果 任务 1.制作导航圆角 提示:使用border-radius实现圆角 2.制作导航立体风格 提示:使用box-shadow实现立体风格 3.制 ...

  9. HttpURLConnection&HttpClient网络通信

    一:HttpURLConnection简介: 用于发送或者接受HTTP协议请求的类,获得的数据可以是任意类型和长度,这个类可以用于发送和接收流数据,其长度事先不知道. 使用这个类遵循一下模式: 获得一 ...

  10. 关于近期需要学习sqlserver2008

    在胜利油田物探院借了一本书叫做 sqlserver2008宝典 第二版,但是看不下去 下面打算直接安装数据库上手了,边练边学