经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Python » 查看文章
Django 模型层之多表操作
来源:cnblogs  作者:Yven  时间:2018/11/14 10:03:13  对本文有异议

一.创建模型

实例:

  1. 作者表:
  2. 拥有字段:姓名(name),性别(sex),该表与书籍表之间为多对多的关系
  3. 作者详情表:
  4. 拥有字段:地址(addr),手机号(phone),该表与作者表之间为一对一的关系
  5. 出版社表:
  6. 拥有字段:名字(name),地址(addr),该表与书籍表之间为一对多的关系
  7. 书籍表:
  8. 拥有字段:书名(name),单价(price)
  9. 分析:一本书可以拥有多个作者,一个作者可以写多本书,所有作者与书籍之间为多对多的关联关系(Many-To-Many);一本书只有一个出版社,但是一个出版社可以出版多种书籍,所以出版社和书籍之间是一对多的关联关系(One-To-Many);作者与作者详情就是一对一关联关系(One-To-One)

所以在Models.py下创建模型如下

  1. class Publish(models.Model):
  2. name = models.CharField(max_length=255)
  3. addr = models.CharField(max_length=255)
  4. def __str__(self):
  5. return self.name
  6. class Author(models.Model):
  7. id = models.AutoField(primary_key=True)
  8. name = models.CharField(max_length=255)
  9. sex = models.IntegerField()
  10. authordetail = models.OneToOneField(to='AuthorDetail')
  11. def __str__(self):
  12. return self.name
  13. class AuthorDetail(models.Model):
  14. id = models.AutoField(primary_key=True)
  15. addr = models.CharField(max_length=255)
  16. phone = models.CharField(max_length=255)
  17. class Book(models.Model):
  18. id = models.AutoField(primary_key=True)
  19. name = models.CharField(max_length=255)
  20. price = models.DecimalField(max_digits=5, decimal_places=2)
  21. # 外键,关联关系写在一对多中多的那一方
  22. publish = models.ForeignKey(to=Publish)
  23. authors = models.ManyToManyField(to=Author)
  24. def __str__(self):
  25. return self.name

注意事项:

  1. 1.id字段不写的话会自动添加
  2. 2.对于外键字段,Django会在字段名上添加"_id"来创建数据库中的列名
  3. 3.外键字段ForeignKey有一个null=True的设置,你可以赋给它空值None

二.添加表记录

一对一:

  1. # 方式一:
  2. detail_obj = models.AuthorDetail.objects.filter(id=2).first()
  3. models.Author.objects.create(name='Yven',sex=1,authordetail=detail_obj)
  4. # 方式二:
  5. models.Author.objects.create(name='hwt',sex=2,authordetail_id=1)

一对多:

  1. # 方式一:
  2. publish_obj = models.Publish.objects.filter(id=2).first()
  3. models.Book.objects.create(name='水浒传',price=24.5,publish=publish_obj)
  4. # 方式二:
  5. models.Book.objects.create(name='西游记',price=24.5,publish_id=2)

多对多:

  1. # 获得书籍对象
  2. book = models.Book.objects.create(name='水浒传',price=24.5,publish_id=3)
  3. # 获得作者对象
  4. yven = models.Author.objects.get(name='Yven')
  5. hwt = models.Author.objects.get(name='hwt')
  6. # 绑定多对多关系
  7. # add中可以传递对象,可以传递id,也可以传递*列表如:(*[yven,hwt])
  8. book.authors.add(yven,hwt)
  9. #多对多关系其他常用API:
  10. # 将某个特定的对象从被关联对象集合中去除,可以传递对象,可以传递id,也可以传递*列表如:(*[yven,hwt])
  11. book.authors.remove()
  12. # 清空被关联对象集合,无需传参
  13. book.authors.clear()
  14. # 先清空再设置,传递的参数必须是可迭代对象,一般为列表,列表内可以是对象,也可以是id
  15. book.authors.set()

三.基于对象的跨表查询

一对一查询

正向查询(按字段:authordetail)

  1. # 查询作者姓名为Yven的手机号
  2. yven = models.Author.objects.get(name='Yven')
  3. phone = yven.authordetail.phone

反向查询(按表名小写:author)

  1. # 查询手机号为12221321的作者名
  2. authordetail = models.Author.objects.filter(phont='12221321').first()
  3. name = authordetail.author.name

一对多查询

正向查询(按字段:publish)

  1. # 查询西游记的出版社名
  2. book = models.Book.objects.filter(name='西游记').first()
  3. name = book.publish.name

反向查询(按表名小写_set.all():book_set.all())

  1. # 查询pk为2的出版社出版书籍的单价
  2. publish = models.Publish.objects.filter(pk='2').first()
  3. booklist = publish.book_set.all() #QuerySet对象
  4. for obj in booklist:
  5. print(obj.price)

多对多查询

正向查询(按字段.all():publish.all())

  1. # 查询水浒传的所有作者
  2. book = models.Book.objects.get(name='水浒传')
  3. author = book.authors.all()
  4. for i in author:
  5. print(i.name)

反向查询(按表名小写_set.all():book_set.all())

  1. # 查询Yven写的多少有书籍的单价
  2. author = models.Author.objects.get(name='Yven')
  3. book = author.book_set.all()
  4. for i in book:
  5. print(i.price)

四.基于双下划线的跨表查询

Django还提供了一种直观而搞笑的方式在查询(lookups)种表示关联关系,它能自动确认SQL JOIN联系。要做跨关系查询,就使用两个下划线来连接模型(model)间关联字段的名称,知道最终链接到你想要的model为止。

一对一查询

正向查询(按字段):authordetail

  1. # 查询Yven的地址
  2. models.Author.objects.filter(name='Yven').values('authordetail__addr')

反向查询(按表名):author

  1. # 查询Yven的地址
  2. models.AuthorDetail.objects.filter(author__name='Yven').values('addr')

一对多查询

正向查询(按字段):publish

  1. # 查询西游记的出版社名
  2. models.Book.objects.filter(name='西游记').values('publish__name')

反向查询(按表名):book

  1. # 查询西游记的出版社名
  2. models.Publish.objects.filter(book__name='西游记').values('name')

多对多查询

正向查询(按字段):authors

  1. # 查询水浒传的作者性别
  2. models.Book.objects.filter(name='水浒传').values('authors__sex')

反向查询(按表名):book

  1. # 查询水浒传的作者性别
  2. models.Author.objects.filter(book__name='水浒传').values('sex')
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号