zoukankan      html  css  js  c++  java
  • py文件单独调试django ORM的配置

    https://www.cnblogs.com/wu-chao/p/8353315.html

    1.新建一个py文件
    2.代码环境搭建

     1 import os
     2 
     3 if __name__ != '__main__':
     4     exit()
     5 
     6 # 加载django项目的配置信息
     7 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_pro.settings") # 就在manage.py 文件中第8行
     8 # 导Django 并 启动Django项目
     9 import django
    10 django.setup()
    11 
    12 from app01 import models

    3.输入需要测试的查询代码

    13种查询方法

    语法 作用


    all()    查询全部
    get(字段='xx')    查找指定值的对象 没有结果会报错
    filter(条件)     作用同上,没有不会报错 返回列表
    exclude(条件)     排除查询,返回不符合条件的所有对象 返回列表
    values(字段,)     按字段 返回字段值 返回字典
    values_list(字段,)     同上,返回列表,里边是元祖
    order_by(字段)     根据指定字段排序
    reverse()     反向排序! 前提是已经有顺序才能反序
    distinct()     查询结果去重
    count()    取查询到的对象 列表个数
    first()    第一个
    last()    最后一个
    exists()    如果返回列表有数据就返回True,否则返回False

    实例

     1 import os
     2 
     3 # 在py中测试ORM的代码环境搭建:
     4 if __name__ == '__main__':
     5 # 加载django项目的配置信息
     6 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_pro.settings") # 就在manage.py的第六行
     7 # 导Django 并 启动Django项目
     8 import django
     9 django.setup()
    10 
    11 from app01 import models
    12 
    13 # all()查询
    14 ret = models.Person.objects.all()
    15 print(ret)
    16 
    17 # get查询 (查询没有对应结果时会报错) 取到对象
    18 ret = models.Person.objects.get(name='老王')
    19 print(ret)
    20 
    21 # filter(**kwargs) 同get但不报错, 取到对象列表,可以批量查询
    22 # 对象列表 ,在django叫 QuerySet对象
    23 ret = models.Person.objects.filter(id=1) # 查询id1的对象列表
    24 print(ret[0])
    25 
    26 # exclude 排除查询 返回列表
    27 ret = models.Person.objects.exclude(id=1) # 取除id=1之外的所有
    28 print(ret)
    29 
    30 # values 按字段 来查找返回,该字段的值(列表)里边是字典
    31 ret = models.Person.objects.values('id','name')
    32 print(ret) # [{'id': 1, 'name': '小张'}, {'id': 2, 'name': '老王'}]
    33 
    34 # values_list 同上,返回列表,里边是元祖
    35 ret= models.Person.objects.values_list('id','name')
    36 print(ret) # [(1, '小张'), (2, '老王')]
    37 
    38 # order_by 根据指定字段排序
    39 ret = models.Person.objects.order_by('id')
    40 print(ret)
    41 
    42 # reverse 反向排序! 前提是已经有顺序才能反序
    43 ret = models.Person.objects.order_by('id').reverse()
    44 print(ret)
    45 
    46 # distinct() 去重
    47 
    48 # count() 取 查询到的对象 列表个数
    49 
    50 # first() 第一个
    51 
    52 # last() 最后一个
    53 
    54 # exists() 如果返回列表有数据就返回True,否则返回False

    QuerySet与惰性机制

    所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行。

    QuerySet特点:

           <1>  可迭代的 

           <2>  可切片

      <3>惰性计算和缓存机制

     1 def queryset(request):
     2     books=models.Book.objects.all()[:10]  #切片 应用分页
     3     books = models.Book.objects.all()[::2]
     4     book= models.Book.objects.all()[6]    #索引
     5     print(book.title)
     6     for obj in books:                     #可迭代
     7         print(obj.title)
     8     books=models.Book.objects.all()          #惰性计算--->等于一个生成器,不应用books不会执行任何SQL操作
     9     # query_set缓存机制1次数据库查询结果query_set都会对应一块缓存,再次使用该query_set时,不会发生新的SQL操作;
    10     #这样减小了频繁操作数据库给数据库带来的压力;
    11     authors=models.Author.objects.all()
    12     for author in  authors:
    13         print(author.name)
    14     print('-------------------------------------')
    15     models.Author.objects.filter(id=1).update(name='张某')
    16     for author in  authors:
    17         print(author.name)
    18     #但是有时候取出来的数据量太大会撑爆缓存,可以使用迭代器优雅得解决这个问题;
    19     models.Publish.objects.all().iterator()
    20     return HttpResponse('OK')

    ## 增加和查询操作

    * 增

     1 def orm(request):
     2     orm2添加一条记录的方法
     3     单表
     4     1、表.objects.create()
     5     models.Publish.objects.create(name='浙江出版社',addr="浙江.杭州")
     6     models.Classify.objects.create(category='武侠')
     7     models.Author.objects.create(name='金庸',sex='',age=89,university='东吴大学')
     8     2、类实例化:obj=类(属性=XX) obj.save()
     9     obj=models.Author(name='吴承恩',age=518,sex='',university='龙溪学院')
    10     obj.save()
    11     
    12     1对多
    13     1、表.objects.create()
    14     models.Book.objects.create(title='笑傲江湖',price=200,date=1968,classify_id=6, publish_id=6)
    15     2、类实例化:obj=类(属性=X,外键=obj)obj.save()
    16     classify_obj=models.Classify.objects.get(category='武侠')
    17     publish_obj=models.Publish.objects.get(name='河北出版社')
    18     注意以上获取得是和 book对象 向关联的(外键)的对象
    19     book_obj=models.Book(title='西游记',price=234,date=1556,classify=classify_obj,publish=publish_obj)
    20     book_obj.save()
    21     
    22     多对多
    23     如果两表之间存在双向1对N关系,就无法使用外键来描述其关系了;
    24     只能使用多对多的方式,新增第三张表关系描述表;
    25     book=models.Book.objects.get(title='笑傲江湖')
    26     author1=models.Author.objects.get(name='金庸')
    27     author2=models.Author.objects.get(name='张根')
    28     book.author.add(author1,author2)
    29 
    30     书籍和作者是多对多关系,
    31     切记:如果两表之间存在多对多关系,例如书籍相关的所有作者对象集合,作者也关联的所有书籍对象集合
    32     book=models.Book.objects.get(title='西游记')
    33     author=models.Author.objects.get(name='吴承恩')
    34     author2 = models.Author.objects.get(name='张根')
    35     book.author.add(author,author2)
    36     #add()   添加
    37     #clear() 清空
    38     #remove() 删除某个对象
    39     return HttpResponse('OK')

    根据条件判断,增加 更新

    1 根据user=user去查找,如果找到更新 如果没有找到创建defaults={} 中的数据
    2             tk = gen_tcoken(username)
    3             models.Token.objects.update_or_create(user=user, defaults={'token': tk})

    * 删

    1 models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据

    * 改

    1 # 修改方式1 update()
    2     models.Book.objects.filter(id=1).update(price=3)
    3 
    4     #修改方式2 obj.save() 
    5     book_obj=models.Book.objects.get(id=1)
    6     book_obj.price=5
    7     book_obj.save()

    * 查

     1 def ormquery(request):
     2     books=models.Book.objects.all()                               #------query_set对象集合 [对象1、对象2、.... ]
     3     books=models.Book.objects.filter(id__gt=2,price__lt=100) 
     4     book=models.Book.objects.get(title__endswith='')            #---------单个对象,没有找到会报错
     5     book1 = models.Book.objects.filter(title__endswith='').first()
     6     book2 = models.Book.objects.filter(title__icontains='').last()
     7     books=models.Book.objects.values('title','price',             #-------query_set字典集合 [{一条记录},{一条记录} ]
     8                                     'publish__name',
     9                                     'date',
    10                                     'classify__category',         #切记 正向连表:外键字段___对应表字段
    11                                     'author__name',               #反向连表: 小写表名__对应表字段
    12                                     'author__sex',                #区别:正向 外键字段__,反向 小写表名__
    13                                     'author__age',
    14                                     'author__university')
    15 
    16     books=models.Book.objects.values('title','publish__name').distinct()  
    17                                                                   #exclude 按条件排除。。。
    18                                                                   #distinct()去重, exits()查看数据是否存在? 返回 true 和false
    19     a=models.Book.objects.filter(title__icontains='').  
    20     return HttpResponse('OK')

    * 连表查询

     1 反向连表查询:
     2     1、通过object的形式反向连表, obj.小写表名_set.all()
     3     publish=models.Publish.objects.filter(name__contains='湖南').first()
     4     books=publish.book_set.all()
     5     for book in  books:
     6         print(book.title)
     7     通过object的形式反向绑定外键关系
     8     authorobj = models.Author.objects.filter(id=1).first()
     9     objects = models.Book.objects.all()
    10     authorobj.book_set.add(*objects)
    11     authorobj.save()
    12     
    13     2、通过values双下滑线的形式,objs.values("小写表名__字段")
    14     注意对象集合调用values(),正向查询是外键字段__XX,而反向是小写表名__YY看起来比较容易混淆;
    15     books=models.Publish.objects.filter(name__contains='湖南').values('name','book__title')
    16     authors=models.Book.objects.filter(title__icontains='我的').values('author__name')
    17     print(authors)
    18     fifter()也支持__小写表名语法进行连表查询:在publish标查询 出版过《笑傲江湖》的出版社
    19     publishs=models.Publish.objects.filter(book__title='笑傲江湖').values('name')
    20     print(publishs)
    21     查询谁(哪位作者)出版过的书价格大于200元
    22     authors=models.Author.objects.filter(book__price__gt=200).values('name')
    23     print(authors)
    24     通过外键字段正向连表查询,出版自保定的书籍;
    25     city=models.Book.objects.filter(publish__addr__icontains='保定').values('title')
    26     print(city)

     ## 高级操作(牛叉的上下划线)

    * 利用双下划线将字段和对应的操作连接起来

     1 # 获取个数
     2 models.Tb1.objects.filter(name='seven').count()
     3 
     4 # 大于,小于
     5 models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
     6 models.Tb1.objects.filter(id__gte=1)              # 获取id大于等于1的值
     7 models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
     8 models.Tb1.objects.filter(id__lte=10)             # 获取id小于10的值
     9 models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
    10 
    11 # in
    12 models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
    13 models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
    14 
    15 # isnull
    16 Entry.objects.filter(pub_date__isnull=True)
    17 
    18 # contains
    19 models.Tb1.objects.filter(name__contains="ven")
    20 models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
    21 models.Tb1.objects.exclude(name__icontains="ven")
    22 
    23 # range
    24 models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and
    25 
    26 # 其他类似
    27 startswith,istartswith, endswith, iendswith,
    28 
    29 # order by
    30 models.Tb1.objects.filter(name='seven').order_by('id')    # asc
    31 models.Tb1.objects.filter(name='seven').order_by('-id')   # desc
    32 
    33 # group by
    34 from django.db.models import Count, Min, Max, Sum
    35 models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
    36 SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
    37 
    38 # limit 、offset
    39 models.Tb1.objects.all()[10:20]
    40 
    41 # regex正则匹配,iregex 不区分大小写
    42 Entry.objects.get(title__regex=r'^(An?|The) +')
    43 Entry.objects.get(title__iregex=r'^(an?|the) +')
    44 
    45 # date
    46 Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
    47 Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
    48 
    49 # year
    50 Entry.objects.filter(pub_date__year=2005)
    51 Entry.objects.filter(pub_date__year__gte=2005)
    52 
    53 # month
    54 Entry.objects.filter(pub_date__month=12)
    55 Entry.objects.filter(pub_date__month__gte=6)
    56 
    57 # day
    58 Entry.objects.filter(pub_date__day=3)
    59 Entry.objects.filter(pub_date__day__gte=3)
    60 
    61 # week_day
    62 Entry.objects.filter(pub_date__week_day=2)
    63 Entry.objects.filter(pub_date__week_day__gte=2)
    64 
    65 # hour
    66 Event.objects.filter(timestamp__hour=23)
    67 Event.objects.filter(time__hour=5)
    68 Event.objects.filter(timestamp__hour__gte=12)
    69 
    70 # minute
    71 Event.objects.filter(timestamp__minute=29)
    72 Event.objects.filter(time__minute=46)
    73 Event.objects.filter(timestamp__minute__gte=29)
    74 
    75 # second
    76 Event.objects.filter(timestamp__second=31)
    77 Event.objects.filter(time__second=2)
    78 Event.objects.filter(timestamp__second__gte=31)

    ## 其他操作

    # extra
    # extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
    Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
    Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
    Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
    
    # F
    from django.db.models import F
    models.Tb1.objects.update(num=F('num')+1)
    
    
    # Q
    # 方式一:
    Q(nid__gt=10)
    Q(nid=8) | Q(nid__gt=10)
    Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
    # 方式二:
    con = Q()
    q1 = Q()
    q1.connector = 'OR'
    q1.children.append(('id', 1))
    q1.children.append(('id', 10))
    q1.children.append(('id', 9))
    q2 = Q()
    q2.connector = 'OR'
    q2.children.append(('c1', 1))
    q2.children.append(('c1', 10))
    q2.children.append(('c1', 9))
    con.add(q1, 'AND')
    con.add(q2, 'AND')
    
    models.Tb1.objects.filter(con)
    
    
    # 执行原生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()

    ## ORM连表操作

    我们在学习django中的orm的时候,我们可以把一对多,多对多,分为正向和反向查找两种方式。

    正向查找:ForeignKey在 UserInfo表中,如果从UserInfo表开始向其他的表进行查询,这个就是正向操作,反之如果从UserType表去查询其他的表这个就是反向操作。

    • 一对多:models.ForeignKey(其他表)
    • 多对多:models.ManyToManyField(其他表)
    • 一对一:models.OneToOneField(其他表)

    正向连表操作总结:

    所谓正、反向连表操作的认定无非是Foreign_Key字段在哪张表决定的,

    Foreign_Key字段在哪张表就可以哪张表使用Foreign_Key字段连表,反之没有Foreign_Key字段就使用与其关联的 小写表名;

    1对多:对象.外键.关联表字段,values(外键字段__关联表字段)

    多对多:外键字段.all()

    反向连表操作总结:

     通过value、value_list、fifter 方式反向跨表:小写表名__关联表字段

    通过对象的形式反向跨表:小写表面_set().all()

    ## 应用场景

    一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)

    例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。

    多对多:在某表中创建一行数据是,有一个可以多选的下拉框

    例如:创建用户信息,需要为用户指定多个爱好

  • 相关阅读:
    C语言结构体+公用体+枚举训练
    TIFF图像文件格式详解
    Professional CUDA C Programming的代码实例1.1
    C语言数组强化训练
    C语言字符数组与字符串
    文件操作
    MATLAB 与Modelsim之间对测试系统的联合仿真
    FFT实现逆FFT
    眼图——概念与测量(摘记)
    《我的心曾悲伤七次》卡里·纪伯伦
  • 原文地址:https://www.cnblogs.com/linkenpark/p/10911126.html
Copyright © 2011-2022 走看看