Django OneToOneField与ManyToManyFiled三种方式

OneToOneField

表一和表二一对一的关系,相当于把表一拆分成两个表。拆成两个表的目的是表一存放经常查询使用频率高的字段,表二放不经常查询,使用频率不高的表。当 一张表的某一些字段查询的比较频繁,另外一些字段查询的不是特别频繁,把不怎么常用的字段 单独拿出来做成一张表 然后用过一对一关联起来,优势是既保证数据都完整的保存下来,又能保证大部分的检索更快 ORM中的用法OneToOneField(to="")

class Student(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    shuxie = models.DecimalField(max_digits=4, decimal_places=2)
    english = models.DecimalField(max_digits=4, decimal_places=2)
    details = models.OneToOneField(to="Information")


class Information(models.Model):
    id = models.AutoField(primary_key=True)
    gender = models.CharField(max_length=6)
    hobby = models.CharField(max_length=64)
  • 查询例子
  print('ontonofile一对一查询'.center(50))
    student_obj = models.Student.objects.get(id=2)
    print(student_obj.details.hobby)
    student_obj = models.Student.objects.filter(id__gt=2).
    values_list('name','details__hobby')
    print(student_obj)
运行结果:
                 ontonofile一对一查询                  
吹牛
<QuerySet [('李世民', '排球'), ('李红', '足球')]>

ManyToManyFiled多对多三种方式

  1. ORM自动帮我创建第三张表
class Mypublisher(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)

class Mybook(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    publisher = models.ForeignKey(to="Mypublisher", related_name="books")

class Myauthor(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    book = models.ManyToManyField(to="Mybook")
  • 查询事例正向查询
  author_obj = models.Myauthor.objects.filter(id__gt=2)
    for i in author_obj:
        for n in i.book.all():
            print(n.publisher.name)
运行结果
人民教育出版社
人民教育出版社
人民教育出版社
清华教育出版社
人民邮电出版社
清华教育出版社
长江教育出版社
清华教育出版社
author_obj = models.Myauthor.objects.get(id=2).book.values_list(
'title','publisher__name')
    print(author_obj)
<QuerySet [('python教程', '清华教育出版社'), 
('Access在财务中应用', '人民教育出版社'),
 ('VB教程', '长江教育出版社'), 
('电脑维修课程', '清华教育出版社'),
 ('射雕英雄传', '长江教育出版社')]>
  • 反向查询
  book_obj = models.Mybook.objects.get(id=2)
    authors_obj = book_obj.myauthor_set.all()
    for author_obj in authors_obj:
        print(author_obj.name,book_obj.title)
运行结果
小布什 python教程
黄志伟 python教程

2、自己创建第三张表, 利用外键分别关联作者和书
关联查询比较麻烦,因为没办法使用ORM提供的便利方法,

class Author2Book(models.Model):
    id = models.AutoField(primary_key=True)
    author = models.ForeignKey(to="Author")
    book = models.ForeignKey(to="Book")
    class Meta:
        unique_together=("author","book")

查询:

ret=models.Author2Book.objects.filter(author_id=1).values_list('book_id')
ret = [i[0] for i in ret]
ret = models.Book.objects.filter(id__in=ret)
print(ret)
  1. 自己创建第三张表,使用ORM 的ManyToManyFiled()
    使用此种方式创建多对多表的时候,没有 add() remove() 等方法
class Author2Book(models.Model):
    id = models.AutoField(primary_key=True)
    author = models.ForeignKey(to="Author")
    book = models.ForeignKey(to="Book")
    class Meta:
        unique_together=("author","book")


class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    book = models.ManyToManyField(to="Mybook",through="Author2Book",through_fields=("author","book")

through="Author2Book",through_fields=("author","book")与自建的 Author2Book建立关联.through_fields第一个字段多对多设置在哪个表里,多对多设置在Myauthor表里这个表对应的字段是 author.
以上查询方式同ManyToManyFiled多对多三种方式中的第一方式.

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容