DJango周总结二:模型层,单表,多表操作,连表操作,数据库操作,事务

django周复习二
 1,模型层:
  1单表操作:
   13个必会操作总结
    返回QuerySet对象的方法有
    all()
    filter()
    exclude()
    order_by()
    reverse()
    distinct()
    特殊的QuerySet
    values()       返回一个可迭代的字典序列
    values_list() 返回一个可迭代的元祖序列
    返回具体对象的
    get()
    first()
    last()
    返回布尔值的方法有:
    exists()
    返回数字的方法有
    count()


   # 方式1: create
   # book_obj  = models.Book.objects.create(title=‘三国‘,price=19.99,create_time=‘2019-11-11‘)
   # print(book_obj.title)
   # 方式2:对象点save()方法   效率极低,因为每执行一次,相当于从数据库从头到尾执行一遍
   # from datetime import datetime
   # ctime = datetime.now()
   # book_obj = models.Book(title=‘西游记‘,price=96.66,create_time=ctime)
   # book_obj.save()


   # print(models.Book.objects.all())
   # print(models.Book.objects.get(id=1))
   # print(models.Book.objects.get(pk=1))
   """
   pk会自动查找到当前数据的主键字段
   """
   # print(models.Book.objects.filter(pk=2))


   # 1.update
   # models.Book.objects.filter(pk=1).update(title=‘三国演义‘)
   # 2.对象.save()
   # book_obj = models.Book.objects.get(pk=1)
   # book_obj.price = 666.66
   # book_obj.save()

删除  delete()
   # models.Book.objects.filter(pk=2).delete()

# < 1 > all(): 查询所有结果

# < 2 > filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
   # < 3 > get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。(源码就去搂一眼~诠释为何只能是一个对象)
   # < 4 > exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
   # print(models.Book.objects.exclude(pk=1))  # 只要pk不是1的数据全部查询出来

# < 5 > order_by(*field): 对查询结果排序(‘-id‘) / (‘price‘)
   # print(models.Book.objects.order_by(‘price‘))  # 默认是升序
   # print(models.Book.objects.order_by(‘-price‘))  # 加负号就是降序

# < 6 > reverse(): 对查询结果反向排序 >> > 前面要先有排序才能反向
   # print(models.Book.objects.order_by(‘price‘).reverse())

# < 7 > count(): 返回数据库中匹配查询(QuerySet)
   # print(models.Book.objects.count())  # 对查询出来的结果进行一个计数

# 的对象数量。
   # < 8 > first(): 返回第一条记录
   # print(models.Book.objects.filter(pk=1).first())
   # < 9 > last(): 返回最后一条记录
   # print(models.Book.objects.all())
   # print(models.Book.objects.all().last())

# < 10 > exists(): 如果QuerySet包含数据,就返回True,否则返回False
   # print(models.Book.objects.filter(pk=1000))
   # print(models.Book.objects.filter(pk=1000).exists())

# < 11 > values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
   # model的实例化对象,而是一个可迭代的字典序列
   # print(models.Book.objects.values(‘title‘,‘price‘))  # 得到的结果是列表套字典

# < 12 > values_list(*field): 它与values()
   # print(models.Book.objects.values_list(‘title‘,‘price‘))  # 得到的结果是列表套元组

# 非常相似,它返回的是一个元组序列,values返回的是一个字典序列
   # < 13 > distinct(): 从返回结果中剔除重复纪录
   """
   去重的前提是 一定要有完全重复的数据 才能去重
   """
   # print(models.Book.objects.filter(title=‘三国演义‘).distinct())
   # print(models.Book.objects.values(‘title‘,‘price‘,‘create_time‘).distinct())
   
   
  2,神奇的双下划线查询
    字段__
    __gt   大于
    __lt   小于
    __gte  大于等于
    __lte  小于等于
    __in[]   在不在里面
    __range() 在不在某范围,两边都包含
    __contains=‘p‘   判断是否含有p  只能判断小写
    __icontains=‘p‘  判断是否含有p  忽略大小写
    __startswith=‘三‘  判断是否以三开头
    __endswith=‘p‘     判断是否以p结尾
    __year=‘2017‘     查看2017年的
    
    models.Book.objects.filter(price__gte=200)   大于等于
    models.Book.objects.filter(price__lte=200)  小于等于
    models.Book.objects.filter(price__in=[200,300,666.66])  查询价格要么是200,要么是300,要么是666.66
    models.Book.objects.filter(price__range=(200,800))  # 两边都包含  查询价格在200到800之间的
    models.Book.objects.filter(title__contains=‘p‘)  # 仅仅只能拿小写p  查询书籍名字中包含p的
    models.Book.objects.filter(title__icontains=‘p‘)  # 忽略大小写
    models.Book.objects.filter(title__startswith=‘三‘)          查询书籍是以三开头的
    models.Book.objects.filter(title__endswith=‘p‘)
    
    models.Book.objects.filter(create_time__year=‘2017‘)    查询出版日期是2017的年(******)
    
  3,多表操作
   一对多:ForeignKey
   一对一:OnoToOneField  可以用ForeignKey代替ForeignKey(unique=True)
    上面两个关键字所创建出来的字段会自动加上_id后缀
   
   多对多:ManyToManyFiled
   该字段并不会真正的在表中展示出来 它仅仅是一个虚拟字段
    1.告诉orm自动创建第三张表
    2.帮助orm跨表查询
    
   
   2.一对多增删改查:
      publish_id传数字                                                          
      models.Book.objects.create(title=‘三国演义‘,price=189.99,publish_id=1)     
    publish直接传出版社对象                                                       
      publish_obj = models.Publish.objects.filter(pk=2).first()              
      models.Book.objects.create(title=‘红楼梦‘,price=999.99,publish=publish_obj)
                       
      改                                                                      
      传数字的                                                                   
      models.Book.objects.filter(pk=1).update(publish_id=3)                  
      传对象的                                                                   
      publish_obj = models.Publish.objects.filter(pk=2).first()              
      models.Book.objects.filter(pk=1).update(publish=publish_obj)           
                       
      删                                                                      
      models.Publish.objects.filter(pk=2).delete()  # 默认都是级联更新 级联删除          
    
   3,多对多字段的增删改查
     add()       增    传数字,对象
     set()        改   传数字,对象  ,必须是可迭代对象
     remove()     删    传数字,对象
        以上可以传多个
     clear()      删所有   括号内不要传参数
   
     # 增
      add()
      1,add括号中传数字
      
      
          # 主键为6的书籍增加一个作者
        book_obj = models.Book.objects.filter(pk=6).first()
        print(book_obj.authors) 此时为None,就是跳到了第三张表
        
        #对象点击多对多虚拟字段时,会直接多对多的第三张表
        #此时book_obj.authors就是直接跨到第三张表
        book_obj.authors.add(1)  # 此时就是给id为6的书籍添加一个作者
        book_obj.authors.add(2,3)
        # add括号中既可以传一个数字,又可以传多个数字
        # 括号中一个数字,此时就是给id为6的书籍添加一个作者,
        # 所以括号中有几个数字,就是添加几个作者,数字表示的是作者的id号
      
      2,add括号中传对象
        增加一条
            book_obj = models.Book.objects.filter(pk=4).first()
         aut_obj = models.Author.objects.filter(pk=3).first()
         book_obj.authors.add(aut_obj)
        
        增加多条
        
         book_obj = models.Book.objects.filter(pk=5).first()
         book_obj1= models.Book.objects.filter(pk=5).first()
         
         aut_obj = models.Author.objects.filter(pk=2).first()
         aut_obj1= models.Author.objects.filter(pk=1).first()
         aut_obj2 = models.Author.objects.filter(pk=9).first()
         
         book_obj.authors.add(aut_obj,aut_obj1,aut_obj2)
         book_obj1.authors.add(aut_obj1)
        总结:
        add是给书籍添加作者 括号内既可以传数字也可以传作者对象
        并且支持一次性传多个 逗号隔开就可以
        注意 :对象点虚拟字段就是跳到了第三张表
        
        
     改:
      将主键为5的书籍对象 作者修改为2,3
      set()
       括号中以列表的形式,是可迭代对象才可以传一个参数也要以列表的形式
       1,传数字,
       
           book_obj = models.Book.objects.filter(pk=5).first()
        book_obj.authors.set([5,])   传一个参数
        book_obj.authors.set([2,3])  传多个参数
         本质就是修改,有点类似于删除,把不要的删除,把要的留下来
      
       2,传作者对象
       
         aut_obj = models.Author.objects.filter(pk=2).first()
         aut_obj1= models.Author.objects.filter(pk=1).first()
         aut_obj2 = models.Author.objects.filter(pk=9).first()
         
         book_obj.authors.set([aut_obj,aut_obj1,aut_obj2])
   
      总结:
       set()括号内 需要传一个可迭代对象
       可迭代对象  可以是多个数字组合
       也可以是多个对象组合
       但是不能混在一起使用,即不能既有数字,又有对象!!!
       要么纯数字,要么纯对象
       
       
       
     删:
      remove()
       1,传数字
       
          book_obj = models.Book.objects.filter(pk=5).first()
  
       book_obj.authors.remove(3)
       
       2,传对象
       
        aut_obj = models.Author.objects.filter(pk=2).first()
        aut_obj1= models.Author.objects.filter(pk=1).first()
        aut_obj2 = models.Author.objects.filter(pk=9).first()
        
        book_obj.authors.remove(aut_obj)
        book_obj.authors.remove(aut_obj,aut_obj1,aut_obj2)
      总结:
       remove()括号内既可以传数字 也可以传对象
       并且支持传多个,逗号隔开即可
       
       将某本书和作者的关系全部清空,用clear()
       即清空当前这个作者与书籍的关系
       
       book_obj = models.Book.objects.filter(pk=5).first()
       book_obj.authors.clear()
       
       
    跨表查询:
            正向与反向的概念
   
       # 一对一
       # 正向:author---关联字段在author表里--->authordetail  按字段
       # 反向:authordetail---关联字段在author表里--->author  按表名小写
       
        
       # 一对多
       # 正向:book---关联字段在book表里--->publish  按字段
       # 反向:publish---关联字段在book表里--->book  按表名小写_set.all() 因为一个出版社对应着多个图书
       
       # 多对多
       # 正向:book---关联字段在book表里--->author  按字段
       # 反向:author---关联字段在book表里--->book  按表名小写_set.all() 因为一个作者对应着多个图书
       
       
       正向查询按外键字段
       反向查询按表名小写
       
       基于对象的跨表查询(子查询:将一张表的查询结果当做另外一个查询语句的条件)
       
       强调:在书写orm语句的时候 跟写sql语句一样
       不要尝试着 一次性写完  应该做到写一点看一点再一点
   1,如果外键字段在你当前这张表中,那么如果由你当前这张表向另一张表查询就是正向

关系字段在你当前这张表,由你这张表去查,正向
    关系字段不在你当前这张表,由你这张表去查,反向
    
    正向查询按外键字段
    反向查询按表名小写
    
    
    # 基于对象的跨表查询(子查询:将一张表的查询结果当做另外一个查询语句的条件)
     #查询书籍为4的出版社名称
     book_obj = models.Book.objects.filter(pk=4).first()
     print(book_obj.publish.name)
     print(book_obj.publish.addr)
     # 查询书籍id是5的作者姓名
     book_obj = models.Book.objects.filter(pk=5).first()
     
     print(book_obj.authors)   # app01.Author.None
     #书籍有多个作者,所以拿到为None
     print(book_obj.authors.all()) 拿到的是对象,
     
     当你外键字段对应的值有多个的时候就用all(),为一个的时候就不用all()
       
        # 查询作者是jason的家庭住址
      auth_obj = models.Author.objects.filter(name=‘jason‘).first()
      print(auth_obj.author_detail.addr)
     
      
     反向查询:
          # 查询出版社是东方出版社出版的书籍
       publish_obj = models.Publish.objects.filter(name=‘东方出版社‘).first()
       print(publish_obj.book_set.all())
       # 查询作者是jason写过的所有书籍
       # auth_obj = models.Author.objects.filter(name=‘jason‘).first()
       # print(auth_obj.book_set)
       # print(auth_obj.book_set.all())
       
       # 查询作者号码是120的作者姓名
       auth_obj = models.AuthorDetail.objects.filter(phone=120).first()
       print(auth_obj.author.name)
       print(auth_obj.author.age)
       
     总结:
      反向查询,当你反向查询的结果是多个的时候就需要加 _set
              当你反向查询的结果是一个时就不需要加_set
        即表名小写即可
       跨表查询:可以连续的查询
    # 基于双下划綫的跨表查询(连表查询)
     models.Book.objects.filter().values(‘publish__name‘)
     models.Publish.objects.filter(book__title=‘三‘).values(‘name‘)
     
     models.Book.objects.filter().values(‘authors__author_detail__phone‘)
     # 只要表中有外键字段 你可以通过__无限制的跨表 
    
   F与Q
    F查询
    从数据库中获取字段对应的数据
    库存数大于卖出数
   
    Q查询
     与
      filter(Q(),Q())
      filter(Q()&Q())
     或
      filter(Q()|Q())
     非
      filter(~Q())
      
     补充
      q = Q()
      q.connector = ‘or‘
      q.children.append((‘title‘,‘三‘))
      q.children.append((‘price‘,666))
      models.Book.objects.filter(q)
    
 2,常见字段  
   AutoField()    int primary key auto_increment
   CharField()    varchar()
   IntegerField()   int()
   big....   
   EmailField() varchar(254)
   DateField()      date
   DateTimeField()  datetime
    auto_now:每次修改数据都会更新时间
    auto_now_add:只在第一次创建数据的时候才会更新一次
    
    BooleanField(Field)
     is_delete = BooleanField()
     给该字段传值的时候 你只需要传布尔值即可
     但是对应到数据库  它存的是0和1
    TextField(Field)
     - 文本类型
     用来存大段文本
    
    FileField(Field)
    - 字符串,路径保存在数据库,文件上传到指定目录
    - 参数:
     upload_to = ""      用户上传的文件会自动放到等号后面指定的文件路径中
     storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
   
   自定义char字段
 
    class MyChar(models.Field):
     def __init__(self,max_length,*args,**kwargs):
      self.max_length = max_length
      super().__init__(max_length=max_length,*args,**kwargs)

def db_type(self, connection):
      return ‘char(%s)‘%self.max_length

外键字段
    当你在使用django2.X版本的时候 在建立外键关系时(*****)
    需要你手动添加几个关键点参数
     models.cascade
     db_constraints

3,数据库查询优化
  only与defer
   
  select_releated与prefect_releated
  
  """数据库查询优化"""
   # orm内所有的语句操作 都是惰性查询:只会在你真正需要数据的时候才会走数据库,如果你单单只写orm语句时不会走数据库的
   # 这样设计的好处 在于 减轻数据库的压力 
  # res = models.Book.objects.only(‘title‘)
  # # print(res)
  # for r in res:
  #     # print(r.title)  # 只走一次数据库查询
  #     print(r.price)  # 当你点击一个不是only括号内指定的字段的时候 不会报错 而是会频繁的走数据库查询

# res1 = models.Book.objects.defer(‘title‘)  # defer与only是相反的
  # for r in res1:  # defer会将不是括号内的所有的字段信息 全部查询出来封装对象中
  #     # 一旦你点击了括号内的字段  那么会频繁的走数据库查询
  #     print(r.price)

# select_related与prefetch_related
  # select_related帮你直接连表操作 查询数据   括号内只能放外键字段
  # res = models.Book.objects.all().select_related(‘publish‘)
  # for r in res:
  #     print(r.publish.name)
  # res = models.Book.objects.all().select_related(‘publish__xxx__yyy__ttt‘)
  # print(res)
  # res = models.Book.objects.all()
  """
  select_related:会将括号内外键字段所关联的那张表  直接全部拿过来(可以一次性拿多张表)跟当前表拼接操作
  从而降低你跨表查询 数据库的压力
  
  注意select_related括号只能放外键字段(一对一和一对多)
   res = models.Book.objects.all().select_related(‘外键字段1__外键字段2__外键字段3__外键字段4‘)
  """
  # prefetch_related  不主动连表
  res = models.Book.objects.prefetch_related(‘publish‘)
  """
  不主动连表操作(但是内部给你的感觉像是连表操作了)  而是将book表中的publish全部拿出来  在取publish表中将id对应的所有的数据取出
  res = models.Book.objects.prefetch_related(‘publish‘)
  括号内有几个外键字段 就会走几次数据库查询操作   
  """
  for r in res:
   print(r.publish.name)

4,事务
  
  ACID
   原子性
   一致性
   隔离性
   持久性
  from django.db import transaction

with transaction.atomic():
   """数据库操作
   在该代码块中书写的操作 同属于一个事务
   """
   models.Book.objects.create()
   models.Publish.objects.create()
   # 添加书籍和出版社 就是同一个事务 要么一起成功要么一起失败
  print(‘出了 代码块 事务就结束‘)

5,数据库连接:
  1,在settings.py 文件中进行更改,添加
   DATABASES = {
    ‘default‘: {
     ‘ENGINE‘: ‘django.db.backends.mysql‘,
     ‘NAME‘: ‘day56‘,
     ‘HOST‘:‘127.0.0.1‘,
     ‘USER‘:‘root‘,
     ‘PORT‘:3306,
     ‘PASSWORD‘:‘123‘,
     ‘CHARSET‘:‘utf8‘
    }
   }
  2.在应用或者项目文件夹下的__init__文件中添加:
   import pymysql
   pymysql.install_as_MySQLdb()
   
  3,orm对象关系映射
   表        类
   一条条记录   对象
   记录中的字段  对象.属性
   
   
   首先需要在应用下的models.py中书写模型类
    class User(models.Model):
     # 将id字段设置为User表主键字段  在django orm中 你可以不写主键字典  django会默认给你的表创建一个名为id的主键字段
     # id = models.AutoField(primary_key=True)  # 一旦你自己指定了主键字段 那么django就不会自动再帮你创建了
     username = models.CharField(max_length=32)  # username varchar(32)   CharField必须要指定max_length参数
     password = models.IntegerField()  # password int
     
   *************************需要执行数据库迁移(同步)命令******************************
   python3 manage.py makemigrations  # 仅仅是在小本本上(migrations文件夹)记录数据库的修改 并不会直接操作数据
   python3 manage.py migrate  # 将数据库修改记录 真正同步到数据库
   注意:只要动了models中跟数据库相关的代码 就必须重新执行上面的两条命令 缺一不可(******)

原文地址:https://www.cnblogs.com/Fzhiyuan/p/11564510.html

时间: 2024-10-06 22:42:54

DJango周总结二:模型层,单表,多表操作,连表操作,数据库操作,事务的相关文章

模型层单表操作

模型层单表操作 单表操作 例: 1. 单表的查询 1. 单表查询所有用户:models.Book.objects.all() 得到的是 queryset对象(当成列表),列表里面,一个一个的对象[user1,user2] ? 2. render(request, 'booklist.html', {'book_list': ret}) ? 3. 模板里: {% for user in book_list %} #要循环的内容 {{book.name}} {% endfor%} 4. get请求携

Django框架(模型层:单表查询)

创建表 1.创建模型 创建名为book的app,在book下的models.py中创建模型 from django.db import models # Create your models here. class Book(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=64) pub_data = models.DateField() price = model

BIEE入门(三)业务模型层

正如它的名字所示(Business Model and Mapping Layer),业务逻辑层需要把物理层的数据源以一种业务用户的视角来重新组织物理层的各个数据源(所谓的Mapping),同时在业务逻辑层里,我们将 需要真正构建数据仓库里的星型模型,包括: ·         事实表 ·         维表 ·         维表的层次结构(hierarchy) ·         事实表度量(measure)来提供一个模型供展现层使用,所以在业务逻辑层,用户需要同时具有技术的知识(数据仓

Django基础五之django模型层(一)单表操作

目录 一 ORM简介 二 单表操作 一.创建表 创建模型 2 更多字段和参数 3 settings配置 4.自定义字段(了解) 二.添加表纪录 方式1 方式2(用的多) 方式3:批量插入 三.查询表纪录 查询API(都是重点) 基于双下划线的模糊查询 四.删除表纪录 五.修改表纪录 三 章节作业 1 图书管理系统 2 查询操作练习 四 xxx 本节目录 一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,

Django基础五之django模型层(二)多表操作

目录 一 创建模型 关于db_column和verbose_name 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询(基于join实现的) 进阶练习(连续跨表) 五 聚合查询.分组查询.F查询和Q查询 查询练习 F查询与Q查询 F查询 Q查询 六 ORM执行原生sql语句(了解) 执行原生查询 直接执行自定义SQL 七 Python脚本中调用Django环境(django外部脚本使用models) 八 补充多个app配置models 本节目录 一 创建模型 表和表之间的关系

Django模型层之单表操作

Django模型层之单表操作 一 .ORM简介 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数据库管理软件,例如mysql.oracle.Microsoft SQL Server等. 如果应用程序需要操作数据(比如将用户注册信息永久存放起来),那么我们需要在应用程序中编写原生sql语句,然后使用pymysql模块远程操作mysql数据库,详见图一^①^ 但是直接编写原生sql语句会存在两方面的问题,严

9.17 模型层 ORM 单表操作

1 创建模型 创建名为book的app,在book下的models.py中创建模型: from django.db import models # Create your models here. class Book(models.Model): id=models.AutoField(primary_key=True) title=models.CharField(max_length=32) state=models.BooleanField() pub_date=models.DateF

Django——模型基础(单表)

1.ORM 在MVC或者说MTV设计模式中,模型(M)代表对数据库的操作.但操作数据库需要专门的SQL语句,而Python程序员不是专业的DBA,写的SQL语句可能有点次,于是就有人想到用python语法来操作,这就是ORM. ORM 即:对象—关系—映射(从https://www.cnblogs.com/huang-yc/p/9652935.html盗来一张图,顺便吹下这位博主!) 简单又不太专业的说就是通过映射关系使得一个python语句对应一个SQL语句,这样python程序员无需关心OR

5.Django|模型层--多表关系

多表操作 一对多Book id title price publish email addr 1 php 100 人民出版社 111 北京 2 python 120 沙河出版社 222 沙河 3 go 110 人民出版社 119 北京 4 java 300 人民出版社 111 北京 Book多 id title price publish_id 1 php 100 1 2 python 120 1 3 go 110 2 4 java 300 1 Publish一 id name email ad