zoukankan      html  css  js  c++  java
  • django--orm关系字段(ForeignKey、OneToOneField、ManyToManyField)详解

    django中的关系字段

    1、ForeignKey字段,即外键字段,对应一对多的情况,列如:一本书对应一个出版社,一个出版社可对应多本书。
    2、ManyToManyFiled字段,即多对多字段,对应数据库中一个数据相互可以对应多条,列如:一本书可以有多个作者,一个作者可以有多本书
    3、OneToOneFiled字段,即一对一字段,通过用来将一条数据补常用的数据单独存放,例如对于作者来说,姓名、作品等是常被查询的,而地址、生日这些是补常用的,就可以将这部分数据通过一对一字段对应分表存放

    准备工作:

    from django.db import models
    
    # Create your models here.
    class Publisher(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=12)
        addr = models.TextField()
        date = models.DateField()
    
    class Book(models.Model):
        title = models.CharField(max_length=12)
        price = models.DecimalField(max_digits=6,decimal_places=2)
        isbn = models.CharField(max_length=20,unique=True)
        pulisher = models.ForeignKey(to='Publisher')
    
    class Author(models.Model):
        name = models.CharField(max_length=12)
        gender=models.SmallIntegerField(choices=((1,'男'),(2,'女'),(3,'保密')),default=3)
    
        phone=models.CharField(max_length=11,unique=True)
        email=models.EmailField()
        book = models.ManyToManyField(to='Book',related_name='authors')
        info = models.OneToOneField(to='Authorinfo',related_name='infos')
    
    class Authorinfo(models.Model):
        birthday=models.DateTimeField()
        city=models.CharField(max_length=12)
        is_marry=models.BooleanField()
        income = models.BigIntegerField()
    

    ForeiKeyField

    2、运行django命令:python manage.py makemigrations 和 python manage.py migrate
    3、在数据库中添加数据:
    作者表:

    作者信息表:

    查询数据的方式:

    查询数据方法主要分为两种方式:通过对象查询和通过qureset数据查询,其中每种方式还对应正向查询和反向查询,解释:例如在上面两个表中,一对一字段在作者表中那么根据作者表查信息表就是正向查询,反之为反向查询

    ForeiKeyField正向查询

    通过对象正向查询

    例如查询id=1的作者的详细信息:
    步骤:
    1、获取id=1的作者对象
    2、通过一对一字段获取对象
    3、调用字段属性
    在django脚本中:

    import os
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day65blog.settings")
        import django
        django.setup()
        from app01 import models
        #获取id =1 的数据对象
        obj  = models.Author.objects.get(id=1)
        #通过.一对一字段名的方式获取信息表对象并查看属性
        print(obj.info.country,obj.info.city)
    

    运行结果:

    英国 伦敦
    

    通过对象反向查询

    查询国家=英国 城市=伦敦的的作者
    步骤:
    1、获取满足条件的作者信息表对象
    2、通过.表名方法获取对象(当一对一字段有related_name参数时,用该参数的值替代表名_set)

    from django.db import models
    
    # Create your models here.
    
    
    class Author(models.Model):
        #姓名字段
        name = models.CharField(max_length=12)
        #性别字段,choices参数对应选择1、2、3
        gender = models.SmallIntegerField(choices=((1,'男'),(2,'女'),(3,'保密')),default=3)
        #一对一字段,related_name参数为反向查找时的别名。没有别名反向查找时用
        info = models.OneToOneField(to='Authorinfo',related_name='infos')
    
    class Authorinfo(models.Model):
        #年龄字段
        age = models.SmallIntegerField()
        #国籍
        country = models.CharField(max_length=12)
        #城市
        city = models.CharField(max_length=12)
    
    
    import os
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day65blog.settings")
        import django
        django.setup()
        from app01 import models
    
        #获取信息表对象
        obj = models.Authorinfo.objects.get(country='英国',city='伦敦')
        #通过related_name='infos'反向查询
        print(obj.infos.get_gender_display())
    

    如果 info = models.OneToOneField(to='Authorinfo',related_name='infos')中没有related_name参数,则是如下:

    import os
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day65blog.settings")
        import django
        django.setup()
        from app01 import models
    
        #获取信息表对象
        obj = models.Authorinfo.objects.get(country='英国',city='伦敦')
        #通过表名(小写)反向查询
        print(obj.author.get_gender_display())
    

    通过qureset查询

    正向查询

    查询id=1的作者的国家
    步骤:
    1、获取作者query对象
    2、通过字段__方法

    #正向查找
        #获取queryset数据
        ret = models.Author.objects.filter(id=1)
        #通过字段__方法调用属性
        print(ret.values('info__city'))
        #运行结果:
        # < QuerySet[{'info__city': '伦敦'}] >
    

    反向查询

    #反向查询
        # 获取queryset数据
        ret = models.Authorinfo.objects.filter(city='伦敦')
        # 通过表名__方法调用属性
        # 如果一对一字段有设置related_name参数=infos,表名__=infos
        print(ret.values('author__name'))
    

    ForeignKey

    书籍应出版社为1对多关系即为外键

    通过对象正向查询

    查询id=1的书籍的出版社,方法:对象.关联字段.外表字段

       #获取对象
        obj =Book.objects.get(id=1)
        #对象.字段名.外表属性
        print(obj.pulisher.name)
    

    通过对象反向查询

    查询出版社id=1 的出版社出版的书籍

    #获取出版社对象
        ret = Publisher.objects.get(id=1)
        #对象.表名_set(反向一对多用,反向一对一为对象.表名)得到反向表对象然后调用方法
        ret.book_set.all()
    

    通过qureset查询

        #正向查询书籍id=1的出版社
        ret = Book.objects.filter(id=1)
        print(ret.values('pulisher__name'))
    
        #反向查询id=1出版社出版的书
        ret2= Publisher.objects.filter(id=1)
        print(ret2.values('book__title'))
    

    ManyToManyField

    书籍和作者之间为多对多关系

       #通过对象查询
        #反向查询related_name = authors
        obj = Book.objects.get(id=1)
        obj.authors.all()
    
        #正向查询
        obj1 = Author.objects.get(id=1)
        obj1.book.all()
    
        #通过queryset查询
        #正向查询
        print(Author.objects.filter(id=1).values('book__title'))
        #反向查询
        print(Book.objects.filter(id=1).values('authors__name'))
    

    总结:

  • 相关阅读:
    Spring Cloud Consul Config 知识点
    RabbitMQ 的 docker 镜像使用
    Spring Cloud Config 知识点
    漫画:什么是服务熔断?
    Flux 和 Mono 的区别
    同时引入依赖:spring-cloud-starter-gateway 和 spring-boot-starter-web,报错
    Feign 报错:The bean 'service-producer.FeignClientSpecification', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled.
    Feign和OpenFeign的区别
    Maven 报错:Compilation of Maven projects is supported only if external build is started from an IDE.
    使用 application.properties 中配置的属性,举例:@Value("${server.port}")
  • 原文地址:https://www.cnblogs.com/Kingfan1993/p/9931447.html
Copyright © 2011-2022 走看看