• Django学习笔记(3)orm模型操作


    orm概述
    什么是ORM
    1.Python、PHP、Java是一种开发语言,而MySQL、SQL Server则采用数据库语言,不同语言之间如何实现互操作?
    2.SQL语言包括包括数据定义语言DDL、数据控制语言DCL、数据查询语言DQL、数据操作语言DML等,例如INSERT、DELETE、SELECT、UPDATE操作。
    3.作为开发人员,应该把精力放在核心业务代码的编写上面,而不应该花太多精力跟数据库语言打交道。
    4.ORM(Object-Relational Mapping,对象关系映射)技术可以看做是开发者和数据库之间的桥梁,用于实现数据库和编程语言之间的映射,本质上来看,ORM就是将SQL操作和编程语言操作做了一个翻译。
    5.通过ORM技术来操作数据库,使得开发者无需接触SQL语句,而直接操作对象的属性和方法,大大提高了开发效率。

    orm的功能
    1.映射技术:数据类型映射、类映射、关系映射。例如,每一张数据库表对应开发语言的类,每一个数据字段对应类中的属性。
    2.CRUD操作:CRUD即增删查改操作,在SQL语句中通过Insert、Select、Update、Delete来实现,在ORM库中则需要
    3.通过对应的函数来实现,例如Django ORM通过get、filter、save、delete函数进行操作。
    4.缓存优化:(惰性操作)从数据库查询到的数据以类对象的形式保存在内存,用于随时提取;真正需要查询结果时才执行数据库的select操作,而不是在ORM查询命令执行时查询数据库。

    Models介绍
    1.通常情况,一个Models对应数据库的一张表
    2.Django中Models以类的形式表现
    3.它包含了一些基本字段以及数据的一些行为
    4.我们只需要在类里面进行操作,就可以操作数据库,表,不需要直接使用SQL语句
    5.我们通过创建类来创建数据表,所以对数据库的操作,都是对类与对类的对象进行操作,而不使用sql语句
    6.ORM对象关系映射,实现了对象和数据库的映射,隐藏了数据访问的细节,不需要编写SQL语句

    models的属性与字段(field)

    常用字段类型

    AutoField():一个IntegerField,根据可用ID自动递增。如果没指定主键,就创建它自动设置为主键。

    IntegerField():一个整数;

    FloatField:浮点型

    CharField(max_length = None):字符串字段False

    DateField(auto_now=False, auto_now_add=False):日期;参数auto_now:每次保存对象时,自动设置该字段为当前时间。用于"最后一次修改"的时间戳. 注意,它总是使用当前日期, 默认为False。参数auto_now_add:当对象第一次被创建时自动设置当前时间。用于创建时间的时间戳. 它总是使用当前日期,默认为False;参数auto_now  auto_now_add default是互相排斥的,组合会发生错误

    TImeFiled():时间,参数同DateField

    TextField():一个很长的的文本字段,不超过4000字符

    BooleanField():布尔字段,True或False;

    NullBooleanField():值为Null,True,False;

    DecimalField():十进制浮点数,参数max_digits表示总数,参数decimal_places表示小数点数

    FileField():上传文件字段

    ImageField():用于上传图片并验证图片合法性,需定义upload_to参数,使用本字段需安装pip install pillow图片库;设置upload_to 到某个目录下,需要在settings.py中配置多媒体文件路径: MEDIA_ROOT = os.path.join(BASE_DIR,'static'); models.ImageField(upload_to="article_img" )表示会将从static目录下的article_img文件夹上传图片

    OneToOneField(to, on_delete, parent_link = False):一对一

    ForeignKey(to, on_delete):一对多

    ManyToManyField(to):多对多

    字段参数

    null:如果设置为True,当该字段为空时,Django会将数据库中该字段设置为NULL。默认为False 。

    blank:如果设置为True,该字段允许为空。默认为False。

    default:该字段的默认值。可以是一个值或者是个可调用的对象,如果是个可调用对象,每次实例化模型时都会调用该对象。

    primary_key:如果设置为 True ,将该字段设置为该模型的主键。

    unique:如果设置为 True,这个字段的值必须在整个表中保持唯一。

    verbose_name:任何字段类型都接收一个可选的位置参数,如果未指定Django会自动使用字段的属性名作为该参数值,并且把下划线转换为空格。

    max_length:设置默认长度,一般在CharField、TextField、EmailField等文本字段设置

    choices:设置该字段的可选值,本字段的值是一个二维元素的元祖;元素的第1个值为实际存储的值,第2个值为HTML页面显示的值

    upload_to:设置上传路径,ImageField和FileField字段需要设置此参数,如果路径不存在,会自动创建

    db_index:索引,一般常用来做查询的字段设置为索引,设置为True表示设置索引

    db_constraint:ForeignKey /ManyToManyField/OneToOneField时有这个字段,为False时表示不受母表约束,母表删除数据时外键不受影响

    on_delete:ForeignKey /ManyToManyField/OneToOneField时有这个字段有这个字段,一般值为models.DO_NOTHING时表示母表删除数据时,外键不做任何处理,经常和db_constraint=False连用

    Meta类属性

    verbose_name:设置对象名称(例如usecms),若没有设置,则默认为该类名的小写分词形式,例如类名为CamelCase会被转换为camel case;
    verbose_name_plural:设置对象名称复数(例如usercms),一般设置跟verbose_name一样,verbose_name_plural=verbose_name否则会默认加s;
    db_table:设置映射的数据表名,默认为“应用名_模型名”,即用该模型所在app的名称加本模型类的名称

    ordering :排序规则,按照哪个字段排unique_together序,加上负号是降序 ,ordering = ['id','-create_time']

    unique_together :联合主键   unique_together = ('name','id_card')
    proxy:设置True or False,设置本模型及所有继承本模型的子模型是否为代理模型;
    abstract:设置True or False,设置本模型类是否为抽象基类;如果是抽象基类,那么是不会创建这张表的,这张表用来作为基类被其他的表继承

    写法实例,models.py

     1 from django.db import models
     2 
     3 # Create your models here.
     4 #注:每创建一个table,系统默认第一个字段id,自动新增,无需再次新增
     5 class Category(models.Model):#类名就是表名
     6     name = models.CharField(verbose_name='分类名',max_length=50,unique=True)#定义字符字段name
     7     creat_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)#datetime字段create_time
     8     update_time = models.DateTimeField(verbose_name='修改时间',auto_now=True)
     9     is_delete = models.BooleanField(verbose_name="是否删除",default=False)
    10     method_choice = [
    11         [0,'get'],
    12         [1,'post'],
    13         [2,'put'],
    14         [3,'delete']
    15     ] #枚举
    16     method = models.SmallIntegerField(choices=method_choice,verbose_name='请求方式',default=0)
    17 
    18     class Meta:#Meta用来自定义表内容
    19         db_table = 'category'#自定义table名称
    20         ordering = ['creat_time']#定义排序按照xxx字段排序,默认升序,加减号表示降序
    21         verbose_name = '文章分类'#定义模型中的名称,用于后台管理操作方便
    22         verbose_name_plural = verbose_name#定义复数名词,不然系统会自动在verbose_name后面加s,如'文章分类s'
    23 
    24     def __str__(self):#默认返回系统对象名,需要重新命名来识别
    25         return self.name

    models代码优化:通过类继承方式,将重复字段抽离做为base 抽象类,需要在Meta中设置abstract=True来定义抽象类,避免表被创建

     1 from django.db import models
     2 
     3 # Create your models here.
     4 class BaseModel(models.Model):
     5     create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
     6     update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')
     7     is_delete = models.BooleanField(verbose_name='是否删除', default=False)
     8 
     9     class Meta:
    10         abstract = True #声明这个类只是用来继承的,不会创建这张表
    11 
    12 class CaseSet(BaseModel):#用例集合和用例多对多关系
    13     name = models.CharField(verbose_name='集合名称',max_length=60)
    14     desc = models.CharField(verbose_name='集合描述',max_length=70)
    15     class Meta:
    16         db_table = 'case_set'
    17         verbose_name = '用例集合表'
    18         verbose_name_plural = verbose_name
    19 
    20     def __str__(self):
    21          return self.name
    22 
    23 class Case(BaseModel):
    24     title = models.CharField(verbose_name='用例标题',max_length=80,db_index=True)
    25     desc = models.CharField(verbose_name='用例描述',max_length=120)
    26     method_choice = [
    27         [0,'get'],
    28         [1,'post'],
    29         [2,'put'],
    30         [3,'delete']
    31     ] #枚举
    32     method = models.SmallIntegerField(choices=method_choice,verbose_name='请求方式',default=0)
    33     url = models.URLField(max_length=50,verbose_name='请求url')
    34     params = models.TextField(verbose_name='请求参数')
    35     run_count = models.IntegerField(verbose_name='运行次数',default=0)
    36     run_time = models.DateTimeField(verbose_name='运行时间',default=None)
    37     case_set = models.ManyToManyField(CaseSet,db_constraint=False,verbose_name='用例集合')
    38 
    39     class Meta:
    40         db_table = 'case'
    41         verbose_name = '用例表'
    42         verbose_name_plural = verbose_name
    43 
    44     def __str__(self):
    45          return self.title

    同步到数据库

    1 python manage.py makemigrations #生成迁移文件
    2 python manage.py migrate #同步到数据库中

    QuerySet增删改查

      1 #from user.models import Category#操作哪个table就import哪个类
      2 
      3 # 运算符(不等于/大于/小于/包含)
      4 # Category.objects.filter(name__endswith='xx')#以xx结尾
      5 # Category.objects.filter(name__startswith='xx')#以xx开头
      6 # Category.objects.exclude(name="首页")#exclude-不等于,排除name="首页"的数据
      7     #多级运算,通过多层点
      8 # Category.objects.exclude(name="首页").filter(id__gte=3)#先找name !="首页",再找id>=3
      9 # Category.objects.filter(name__startswith='李').exclude(sex='女')
     10 # print(Category.objects.filter(name__contains='l'))#包含'l'
     11 # Category.objects.filter(name__icontains='l')#包含'l'或者'L',加了'i'就不区分大小写
     12 # print(Category.objects.filter(name__in=['首页','Mysql','python'])) #in
     13 
     14 
     15 # #创建
     16 # obj = models.Article.objects.create(title='title_model',desc='desc1',content='content')
     17 # obj.title = 'new_title'
     18 # obj.save()
     19 #
     20 # obj2 = models.Article(title='title_model',desc='desc1',content='content')
     21 # obj2.save()
     22 
     23 
     24 # #查询
     25 # models.Article.objects.get(id=1)#单个查询,条件只能是唯一的,否则会报错
     26 # models.Article.objects.filter(title='xiaohei',desc='desc1')#多条件查询,返回多条数据,写多个参数就是and
     27 # models.Article.objects.all().filter(title='xiaohei').values()#字典显示,[ {id:1,name:20} , {id:2,name:18} ]
     28 # models.Article.objects.all().count()#个数  .first 获取列表第一个值  .last 获取列表最后一个值
     29 # models.Article.objects.raw('select * from user_article;') # 执行原生sql
     30 # models.Article.objects.filter(title__contains='模糊查询')
     31 # models.Article.objects.filter(title__endswith='开头')
     32 # models.Article.objects.filter(title__startswith='结尾')
     33 # models.Article.objects.filter(title__in=['title1','title2'])
     34 # models.Article.objects.filter(title__isnull=True)#为空
     35 # models.Article.objects.exclude(title__in=['title1','title2'])#排除
     36 # models.Article.objects.filter(read_count__gt=1)
     37 # models.Article.objects.filter(read_count__gte=1)
     38 # models.Article.objects.filter(read_count__lt=1)
     39 # models.Article.objects.filter(read_count__lte=1)
     40 # models.Article.objects.filter(read_count__range=(1,2,3))
     41 
     42 #排序
     43 #Category.objects.all().order_by("is_delete") #通过is_delete字段排序,可通过多字段排序
     44 
     45 #修改
     46 # art = models.Article.objects.get(pk=1)
     47 # art.title = 't1223'
     48 # art.save()
     49 #
     50 # models.Article.objects.filter(title__isnull=True).update(title='小黑') #批量修改
     51 # models.Article.objects.all().update(title='全部修改')#全部修改
     52 
     53 #删除
     54 # Category.objects.all().delete()#删除全表
     55     #删除某条数据
     56 # obj = Category.objects.get(id=3)
     57 # obj.delete()
     58 # obj.save()
     59     #删除部分数据
     60 # Category.objects.filter(id__in=[3,4]).delete(is_delete=False)
     61 
     62 
     63 # #外键操作
     64 # obj = models.Article.objects.get(id=1)
     65 # obj.nav_id = 2 #获取外键信息
     66 # print(obj.nav.name) #获取外键信息
     67 # models.Article.objects.filter(nav__name='abc') #按照外键的字段筛选,外键名称__字段名
     68  
     69 #反向查询
     70 # art_obj = models.Article.objects.get(pk=1)
     71 # nav_obj = models.Nav.objects.get(pk=2)
     72 # print(nav_obj.article_set.filter())#外键反向查询
     73 # print(nav_obj.article_set.count())#外键反向查询
     74 # nav_obj.article_set.add(art_obj)#添加
     75 # nav_obj.article_set.remove(art_obj)#删除
     76 # nav_obj.article_set.clear()#清空
     77  
     78 #多对多
     79  
     80  
     81  
     82 # models.CaseSet.objects.create(name='主流程用例',desc='主流程')
     83 # models.CaseSet.objects.create(name='冒烟用例',desc='冒烟用例')
     84 #
     85 # models.Case.objects.create(title='登录')
     86 # models.Case.objects.create(title='注册')
     87 # models.Case.objects.create(title='订购')
     88 # models.Case.objects.create(title='支付')
     89 # models.Case.objects.create(title='充值')
     90 # models.Case.objects.create(title='发货')
     91  
     92 # c1 = models.Case.objects.get(pk=1)
     93 # c2 = models.Case.objects.get(pk=2)
     94 # c3 = models.Case.objects.get(pk=3)
     95 # s1 = models.CaseSet.objects.get(pk=1)
     96 # s2 = models.CaseSet.objects.get(pk=2)
     97  
     98 # s2.case_set.add(c2,c3)
     99 # s2.case_set.remove(c2,c3)
    100 # s2.case_set.clear()#清空
    101  
    102 # print(c2.case_set.all()) #查看用例在几个集合里面
    103 # print(s2.case_set.all()) #查看集合里面有多少用例
    104  
    105  
    106  
    107 #一对一
    108 #from hashlib import md5
    109 #models.Account.objects.create(account_id=md5('niuhanyang'.encode()).hexdigest())
    110 #models.Account.objects.create(account_id=md5('niuhanyang2'.encode()).hexdigest())
    111 #models.Account.objects.create(account_id=md5('niuhanyang3'.encode()).hexdigest())
    112  
    113 # models.User.objects.create(username='niuhanyang',password='123456',account_id='58e006ecfce801c5e98311c96d32510f')
    114 # u = models.User.objects.get(pk=1)
    115 # print(u.account_id)
    116 # print(u.account.money)
    117 #
    118 # acc = models.Account.objects.get(pk='58e006ecfce801c5e98311c96d32510f')
    119 # print(acc.user.username)
    120 # print(acc.user.password)

    表结构如下图:

    一对一,user表和account表

    nav表,外键,一对多

    case表和case_set表

     

    QuerySet补充:

      1.或者关系, Q,多个条件通过 | 分割  

    1 from django.db.models import Q
    2 
    3             case_sets = models.Case.objects.filter(Q(title__contains=search) |
    4                                    Q(desc__contains=search) |
    5                                    Q(url__contains=search) |
    6                                    Q(params__contains=search))

      

  • 相关阅读:
    二:虚拟游戏摇杆
    一:AndEngine的小例子
    打造属于自己的安卓Metro界面
    linux设备驱动第四篇:驱动调试方法
    C# 二叉查找树实现
    初识 Angular 体会
    C# 霍夫曼二叉树压缩算法实现
    TypeScript笔记[5]泛型+Dictionary 转
    Axiom3D学习日记 5.Frame Listeners, and Input Handling
    Axiom3D学习日记 4.地形,天空,雾
  • 原文地址:https://www.cnblogs.com/bugoobird/p/13308496.html
Copyright © 2020-2023  润新知