zoukankan      html  css  js  c++  java
  • ORM

    ORM是什么

      ORM实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于数据库,通过简单的配置就可以轻松更换数据库,这减轻了开发人员的工作量. 

      对象和关系型数据库的映射

    必会13条:

    1. 返回对象列表的
    all()   Book.objects.all()
    filter()
    exclude()
    order_by()
    reverse()
    distinct()
    values() {}
    values_list() ()

    2. 获取对象的
    get()
    first()
    last()

    3. 返回数字
    count()

    4. 返回布尔值
    exists()

    单表双下: 

     

    基于双下划线的模糊查询,单表中双下表示比较这个字段.

       Book.objects.filter(price__in=[100,200,300]) #price在这个列表内的
         Book.objects.filter(price__gt=100)  #price大于100
         Book.objects.filter(price__lt=100)   ##price小于100
         Book.objects.filter(price__range=[100,200])  #pirce在100到200之间
         Book.objects.filter(title__contains="python") # 模糊查询titile包含ptyhon,区分大小写
         Book.objects.filter(title__icontains="python")  # 不区分大小写
         Book.objects.filter(title__startswith="py")   #title以py开头
         Book.objects.filter(pub_date__year=2012)  #pub_data是2012年的
         Book.objects.filter(pub_date__year__gt=2012) #pub_data是2012年后的

    id__gt
    id__lt
    id__lte
    id__gte

    id__in=[]
    id__range=[1,4]

    contains= ''
    icontains= ''

    startswith = ''
    istartswith = ''
    endswith = ''
    iendswith = ''

    isnull = True


    __year

     

    FK外键

      publish=models.ForeignKey(to="Publish",to_field="nid",relate_name="xxx",on_delete=models.CASCADE)

    m2m 多对多

     

      authors=models.ManyToManyField(to='Author')     #authors不是一个真实的字段.只是ORM层面建立的一个多对多关系.用authors关联作者表.

    author_obj.books --》管理对象
    author_obj.books.add()
    author_obj.books.remove()
    author_obj.books.clear()
    author_obj.books.set() []
    author_obj.books.create()

    book_obj.authors --》管理对象

    跨表双下

    正相查

    反向查

    聚合

       #查书的平均价格  

      Book.objects.all().aggregate(AVG("price"))  

      #查书的最高价,最低价
      Book.objects.aggregate( Max('price'), Min('price'))

    分组

      跨表分组查询本质就是将关联表join成一张表,再按单表的思路进行分组查询

    Employee.objects.values("dep").annotate(avg=AVG("salary"))
    筛选出部门 annoteta是按前面的内容分组

    # 查询每一个作者的名字以及出版书籍的最高价格
    Author.objects.annotate(max_price=Max("book__price")).values("name","max_price")

    # 查询96年以后出生的每一个作者的名字以及出版书籍的最高价格
    Author.objects.filter(birthday__year__gt=1996).annotate(max_price=Max("book__price")).values("name","max_price")

    # 查询不止一个作者的书籍名称以及关联的作者个数
    Book.objects.all().annotate(c=Count("authors")).filter(c__gt=1).values("title","c")

    # 查询部门1的每一个销售的名字以及今天对应的成单量
    Userinfo.objects.filter(depart_id=1).filter(customer__deal_date=now).annotate(c=Count("customers")).values("name","c")

    统计每一本书的作者个数
    ret=Book.objects.annotate(authorsNum=Count('authors__name')

       Book.objects.filter(commnetNum__lt=F('keepNum'))  #查评论数小于keepNum的
      Book.objects.all().update(price=F("price")+30)  #所有书的价格加30

    Q: 查询条件or的关系

    用|分割不同的Q查询条件,
    查询作者名称是max或ding的书
    bookList=Book.objects.filter(Q(authors__name="max")|Q(authors__name="ding"))


      Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询
      bookList=Book.objects.filter(Q(authors__name="max") & ~Q(publishDate__year=2017)).values_list("title")

      Q 对象,它必须位于所有关键字参数的前面。
      Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),title__icontains="python")

    2种查询方式

      1. 基于对象查询  对应sql的子查询

        正向:  按字段查

            book_obj.authors.all()

        反向: 小写表名_set/related_name

           author_obj.book_set.all()  

      2. 基于双下划线查询  对应sql的join连表查询

        正向:  按字段

             Book.objects.filter(title="python").values("publish__name")     #查python的出版社名称

        反向: 按小写表名
           Author.objects.filter(name__startswith="a").values("book__title")   #查姓名是a开头的作者有哪些书

    中介模型:

      M2M类型自动生成第三张表,但是第三张不可修改, 如果想修改第三张表例如添加字段怎么办?  用中介模型, 既可以自定义第三张表字段 也可以继续使用orm的语法.

        class Student(models.Model):
                name = models.CharField( max_length=32)
                courses=models.ManyToManyField("Courses",through="Score") # 告诉djaong用Source表做第三张表
                                    
           class Course(models.Model):
                name = models.CharField( max_length=32)    
                                                                    
           class Score(models.Model):
                 student=models.ForeignKey("Student")
                 course=models.ForeignKey("Course")
                 score=models.IntegerField()

    使用ORM步骤:

    step1 定义模型类:


    class Book(models.Model): id=models.AutoField(primary_key=True) title=models.CharField(max_length=32,verbose_name="书籍名称") # CharField需要max_length参数来指定VARCHAR数据库字段的大小 state=models.BooleanField() pub_date=models.DateField() price=models.DecimalField(max_digits=8,decimal_places=2) publish=models.CharField(max_length=32) def __str__(self): return self.title class Meta: app_label="APP01" db_table="appBook" # 自定义表名,默认显示app_小写类名 unique_together=["title","price"] #设置联合唯一 verbose_name="书籍" #设置admin中表显示名称 ordering=["price"] #设置这个表以price字段排序

      模型类常用字段:

    <1> CharField
                            字符串字段, 用于较短的字符串.
                    <2> IntegerField
                            用于保存整数.
     
                    <3> FloatField
                            浮点数. 必须提供两个参数max_digits总位数  和decimal_places小数位数: e.gmodels.FloatField(..., max_digits=5, decimal_places=2)                         
                     
                    <4> AutoField:自增 整型
                            系统会自动添加一个名为id的自增的整型主键字段到你的 model.
                            默认名为id,可以修改名称:自定义一个主键:my_id=models.AutoField(primary_key=True)                    
                     
                    <5> BooleanField
                            A true/false field. admin 用 checkbox 来表示此类字段.
                     
                    <6> TextField
                            一个容量很大的文本字段.
                            admin 用一个 <textarea> (文本区域)表示该字段数据.(一个多行编辑框).
                     
                    <7> EmailField
                            一个带有检查Email合法性的 CharField,不接受 maxlength 参数.
                     
                    <8> DateField
                    
                            一个日期字段. 共有下列额外的可选参数:
                            Argument    描述
                            auto_now    每次修改时自动修改为当前时间. 通常用于表示 "last-modified" 时间戳.
                            auto_now_add  对象创建时自动添加到当前时间
                            (仅仅在admin中有意义...)
                     
                    <9> DateTimeField
                             一个日期时间字段. 类似 DateField 支持同样的附加选项.
                     
                    <10> ImageField
                            类似 FileField, 不过要校验上传对象是否是一个合法图片.#它有两个可选参数:height_field和width_field,
                            如果提供这两个参数,则图片将按提供的高度和宽度规格保存.                                
                               
               
               字段的参数:
                        (1)null 默认为False。
                           null=True 该字段不必填,是数据库的限制. 
                           
                           blank  默认为False。
                                 blank=True  admin中不必填,是admin的限制. 通常null=True和blank=True一起设置                                     
                                要注意,blank与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
                                如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。
                             
                        (2)default
                         
                            字段默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。
                         
                        (3)primary_key                     
                            如果为True,那么这个字段就是模型的主键。如果没指定字段的primary_key=True,
                            Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
                            否则没必要设置任何一个字段的primary_key=True。
                         
                        (4)unique 设置唯一,例如订单号设置为unique                     
                            如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的
                         
                        (5)choices
                                由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是下拉框,下拉框的选项就是choices 中的选项。
    model常用字段和参数

    step2.在settings中配置:

                        DATABASES = {
                            'default': {
                                'ENGINE': 'django.db.backends.mysql',
                                'NAME':'bms',           # 要连接的数据库,连接前需要创建好
                                'USER':'root',        # 连接数据库的用户名
                                'PASSWORD':'',        # 连接数据库的密码
                                'HOST':'127.0.0.1',       # 连接主机,默认本级
                                'PORT':3306            #  端口 默认3306
                            },
                            
                            'app01': {     #指定app01的配置,没有指定用default
                                'ENGINE': 'django.db.backends.mysql',
                                'NAME':'bms',           # 要连接的数据库,连接前需要创建好
                                'USER':'root',        # 连接数据库的用户名
                                'PASSWORD':'',        # 连接数据库的密码
                                'HOST':'127.0.0.1',       # 连接主机,默认本级
                                'PORT':3306            #  端口 默认3306
                            },                        
                        }

    step3 项目名文件下的__init__,在里面写入:

              import pymysql
                pymysql.install_as_MySQLdb()
                # 因为django默认驱动是MySQLdb,可是MySQLdb 对于py3支持不好,所以我们需要的驱动是PyMySQL.

    step4 通过迁移的命令创建数据表:

              python manage.py makemigrations
              python manage.py migrate        

    step5 如果想打印orm转换过程中的sql,在settings中配置:

          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,模型类的create
                    book_obj=Book.objects.create(title="python葵花宝典",state=True,price=100,publish="苹果出版社",pub_date="2012-12-12")
         #方法2,创建类对象再save()
                    book_obj=Book(title="python葵花宝典",state=True,price=100,publish="苹果出版社",pub_date="2012-12-12")
                    book_obj.save()
  • 相关阅读:
    Oracle 数据块,文件块转换,查看数据块对像
    逆向与汇编视频(36课) IDA 使用
    VC++消息钩子编程
    VS2008中opengl配置
    BSP技术详解3有图有真相
    BSP技术详解1有图有真相
    oracle 跟踪文件和转储命令
    BSP技术详解2有图有真相
    Recognizing and Learning Object Categories 连接放送
    自学MVC看这里——全网最全ASP.NET MVC 教程汇总
  • 原文地址:https://www.cnblogs.com/dingyunfeng/p/10506714.html
Copyright © 2011-2022 走看看