• django的orm框架(进阶篇)


    extra 
    在QuerySet的基础上继续执行子语句 
    extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None) 
    select-select_params
    tmp = models.Book.objects.all().extra(select={"n":"select count(1) from app05_book"})
    for i in tmp:
        print(i.title, i.n)
    书一 6
    书二 6
    书三(第) 6
    书四(第) 6
    书五(第) 6
    书六(第) 6
    select占位符
     
    tmp = models.Book.objects.all().extra(select={"n":"select count(1) from app05_book WHERE id>%s"},select_params=[3,])
    for i in tmp:
        print(i.title, i.n)
    书一 3
    书二 3
    书三(第) 3
    书四(第) 3
    书五(第) 3
    书六(第) 3
    where-params
    models.Book.objects.extra(where=["title=%s"],params=["书一"])
    <QuerySet [<Book: 书一>]>
    1
    2
    models.Book.objects.extra(where=["title='书一' or title='书二'"])
    <QuerySet [<Book: 书一>, <Book: 书二>]>
    and关系
    models.Book.objects.extra(where=["title='书一'","id=2"])
    <QuerySet []>
    举个例子:
    models.UserInfo.objects.extra(
                        select={'newid':'select count(1) from app01_usertype where id>%s'},
                        select_params=[1,],
                        where = ['age>%s'],
                        params=[18,],
                        order_by=['-age'],
                        tables=['app01_usertype']
                    )
                    """
                    select 
                        app01_userinfo.id,
                        (select count(1) from app01_usertype where id>1) as newid
                    from app01_userinfo,app01_usertype
                    where 
                        app01_userinfo.age > 18
                    order by 
                        app01_userinfo.age desc
                    """
    # 执行原生SQL
    # 更高灵活度的方式执行原生SQL语句
    # from django.db import connection, connections
    # cursor = connection.cursor()  # cursor = connections['default'].cursor()
    # cursor.execute("""SELECT * from auth_user where id = %s""", [1])
    # row = cursor.fetchone()
    QuerySet高级操作
    去重
    def distinct(self, *field_names)
    models.Book.objects.values("title").distinct()
    <QuerySet [{'title': '书一'}, {'title': '书三(第)'}, {'title': '书四(第)'}, {'title': '书五(第)'}, {'title': '书六(第)'}]>
    select_related实现表之间进行一对一和多对一优化
    def select_related(self, *fields)
        性能相关:表之间进行join连表操作,一次性获取关联的数据。
        总结:
        1. select_related主要针一对一和多对一关系进行优化。
        2. select_related使用SQL的JOIN语句进行优化,通过减少SQL查询的次数来进行优化、提高性能。
    实例代码如下:
    tmp = models.Book.objects.all()
    for i in tmp:
        print(i.publisher.name)
    沙河出版社
    沙河出版社
    三里屯
    五道口
    国贸
    五道口
    a2 = models.Book.objects.all().select_related("publisher")
    for i in a2:
        print(i.publisher.name)
    沙河出版社
    沙河出版社
    五道口
    五道口
    三里屯
    国贸
    以上代码中第一种查询方式会查询数据库六次,第二种方式会查询数据库次数为1次
    prefetch_related实现表之间进行一对多和多对多优化 
    只能正向查询~且不能跨表
    def prefetch_related(self, *lookups)
        性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。
        总结:
        1. 对于多对多字段(ManyToManyField)和一对多字段,可以使用prefetch_related()来进行优化。
        2. prefetch_related()的优化方式是分别查询每个表,然后用Python处理他们之间的关系。
    1
    2
    3
    4
    5
    6
    实例代码如下:
    tmp = models.Author.objects.all().prefetch_related("books")
    for i in tmp:
        print(i.books.all())
    <QuerySet [<Book: 书一>, <Book: 书一>]>
    <QuerySet [<Book: 书一>, <Book: 书三(第)>]>
    <QuerySet [<Book: 书一>]>
    <QuerySet []>
    defer
     def defer(self, *fields):
        models.UserInfo.objects.defer('username','id')
        或
        models.UserInfo.objects.filter(...).defer('username','id')
        #映射中排除某列数据
    1
    2
    3
    4
    5
    实例代码如下:
    a = models.Author.objects.all().defer("name")
    for i in a:
        print(i)
    小一
    小二
    小三
    小四
    a = models.Author.objects.all().defer("name").values()
    for i in a:
        print(i)
    {'id': 1, 'name': '小一', 'author_detail_id': 1}
    {'id': 2, 'name': '小二', 'author_detail_id': 2}
    {'id': 3, 'name': '小三', 'author_detail_id': 3}
    {'id': 4, 'name': '小四', 'author_detail_id': 4}
    a = models.Author.objects.all().defer(“name”).values() 
    虽然在查询中排除name字段,但是在循环中如果要输出关于name的信息,那么依然会继续查询输出name
    only
     def only(self, *fields):
        #仅取某个表中的数据
         models.UserInfo.objects.only('username','id')
         或
         models.UserInfo.objects.filter(...).only('username','id')
    示例代码如下:
    a = models.Author.objects.only("name")
    for i in a:
        print(i)
    小一
    小二
    小三
    raw执行原生SQL 
    执行原生SQL
    tmp = models.Author.objects.raw("select * from app05_author")
    for i in tmp:
        print(i.name)
    小一
    小二
    小三
    小四
    为原生SQL设置参数
    a = models.Book.objects.raw("select id from app05_book WHERE id>%s",params=[3,])
    for i in a:
        print(i)
    书四(第)
    书五(第)
    书六(第)
    dates
    def dates(self, field_name, kind, order='ASC'):
        # 根据时间进行某一部分进行去重查找并截取指定内容
        # kind只能是:"year"(年), "month"(年-月), "day"(年-月-日)
        # order只能是:"ASC"  "DESC"
        # 并获取转换后的时间
            - year : 年-01-01
            - month: 年-月-01
            - day  : 年-月-日
        models.DatePlus.objects.dates('ctime','day','DESC')
    示例代码如下: 
    models.Book.objects.all().dates("publish_day","year","DESC")
    <QuerySet [datetime.date(2018, 1, 1), datetime.date(2017, 1, 1)]>
    models.Book.objects.all().dates("publish_day","month","DESC")
    <QuerySet [datetime.date(2018, 4, 1), datetime.date(2018, 1, 1), datetime.date(2017, 1, 1)]>
    models.Book.objects.all().dates("publish_day","day","DESC")
    <QuerySet [datetime.date(2018, 4, 12), datetime.date(2018, 1, 29), datetime.date(2018, 1, 25), datetime.date(2018, 1, 19), datetime.date(2018, 1, 11), datetime.date(2017, 1, 18)]>
    datetimes
    def datetimes(self, field_name, kind, order='ASC', tzinfo=None):
        # 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间
        # kind只能是 "year", "month", "day", "hour", "minute", "second"
        # order只能是:"ASC"  "DESC"
        # tzinfo时区对象
        models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.UTC)
        models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.timezone('Asia/Shanghai'))
        """
        pip3 install pytz
        import pytz
        pytz.all_timezones
        pytz.timezone(‘Asia/Shanghai’)
        """
     
    bulk_create 
    参数为一次性插入的个数
    objs = [models.Publisher(name="aaa",addr="aaa"),models.Publisher(name="bbb",addr="bbb")]
    models.Publisher.objects.bulk_create(objs,2)
    [<Publisher: aaa>, <Publisher: bbb>]
    get_or_create 
    # 如果存在,则获取,否则,创建 
    # defaults 指定创建时,其他字段的值
    models.Publisher.objects.get_or_create(name="沙河出版社")
    (<Publisher: 沙河出版社>, False)
    models.Publisher.objects.get_or_create(name="沙河出版社1")
    (<Publisher: 沙河出版社1>, True)
    models.Publisher.objects.get_or_create(name="沙河出版1",addr="sss")
    (<Publisher: 沙河出版1>, True)
    models.Publisher.objects.get_or_create(name="沙河版1",defaults={"addr":"sdfsdsf"})
    (<Publisher: 沙河版1>, True)
    update_or_create 
    如果存在,则更新,否则,创建 
    defaults 指定创建时或更新时的其他字段
    obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 1})
    in_bulk 
    # 根据主键ID进行查找 
    id_list = [11,21,31] 
    models.DDD.objects.in_bulk(id_list)
    from app05 import models
    models.Book.objects.in_bulk([1,2,3])
    (0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
    (0.001) SELECT VERSION(); args=None
    (0.002) SELECT `app05_book`.`id`, `app05_book`.`title`, `app05_book`.`price`, `app05_book`.`publish_day`, `app05_book`.`publisher_id` FROM `app05_book` WHERE `app05_book`.`id` IN (1, 2, 3); args=(1, 2, 3)
    {1: <Book: 书一>, 2: <Book: 书一>, 3: <Book: 书三(第)>}
  • 相关阅读:
    构建之法读书笔记 第4章 两人合作
    ASE19 团队项目 alpha 阶段 Frontend 组 scrum9 记录
    ASE —— 第二次结对作业
    ASE —— 第一次结对作业
    高级软件工程 —— 第一周博客作业
    软工个人总结
    六月上团队项目心得
    团队项目心得
    结对编程收获
    结对作业——随机生成四则运算(Core 第7组)
  • 原文地址:https://www.cnblogs.com/zhangtq/p/10536797.html
Copyright © 2020-2023  润新知