Django-ORM系统详述

Object Relational Mapping,对象关系映射,为了解决面向对象与关系数据库存在的互不匹配的技术。

ORM的优势

ORM解决的主要问题是对象和关系的映射。它通常将一个类和一张表一一对应,类的每个实例对应表中的一条记录,类的每个属性对应表中的每个字段。

ORM提供了对数据库的映射,不用直接编写SQL代码,只需操作对象就能对数据库操作数据。

让软件开发人员专注于业务逻辑的处理,提高了开发效率。

ORM的劣势

ORM的缺点是会在一定程度上牺牲程序的执行效率。

ORM的操作是有限的,也就是ORM定义好的操作是可以完成的,一些复杂的查询操作是完成不了。

ORM用多了SQL语句就不会写了,关系数据库相关技能退化...

使用mysql数据库的流程

  1. 创建一个mysql数据库;

  2. 在settings.py中配置数据库:

     DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',   # 引擎
            'NAME': '数据库名',   # 数据库名称
            'HOST': 'IP地址',      # IP
            'PORT': 3306,   # 端口号
            'USER': '用户名',       # 用户名
            'PASSWORD': '密码'      # 密码
        }
     }
  3. 使用pymysql模块连接mysql数据库。

    写在与settings同级目录下的__init__.py

    import pymysql
    pymysql.install_as_MySQLdb()
  4. 写对应关系,在app下的models.py中写类,定义数据表。

     class User(models.Model):
        username = models.CharField(max_length=32)  # username  varchar(32)
        password = models.CharField(max_length=32)  # password  varchar(32)
  5. 执行数据库迁移的命令

     python36 manage.py  makemigrations   # 记录下models.py的变更记录  
     ​
     python manage.py migrate   # 变更记录同步到数据库
  6. 所有要实现的功能放在views.py中,如果要用数据库,应该将数据库的models导入到该文件

    from django.shortcuts import render,redirect
    from app01 import models  
     ​
     def login(request):
        if request.method == 'GET':
            return render(request,'login.html')
     ​
        elif request.method == "POST":
            # 获取提交数据
            user = request.POST.get("username")
            pwd = request.POST.get("password")
            # ret = models.inf.objects.get(username=user,password=pwd) # get方法有一个特点是查不到数据或者查到多个数据时,会报错
            ret = models.inf.objects.filter(username=user,password=pwd)
            if ret:
                return redirect("/home/")
            else:
                return render(request,'login.html')
     ​
     def home(request):
        return render(request,'home.html')

注意

 进行查询操作时
 ret = models.User.objects.get(username=user, ) # 找不到就报错  找到多个也报错
 ret = models.User.objects.filter(username=user, )  # 过滤筛选,获取满足条件的所有的对象,存放在列表中

常用数据类型

常用字段

AutoField

自增的整形字段,必填参数primary_key=True,则成为数据库的主键。无该字段时,django自动创建。

一个model不能有两个AutoField字段。

IntegerField

一个整数类型。数值的范围是 -2147483648 ~ 2147483647。

CharField

字符类型,必须提供max_length参数。max_length表示字符的长度。

DateField

日期类型,日期格式为YYYY-MM-DD,相当于Python中的datetime.date的实例。

参数:

  • auto_now:每次修改时修改为当前日期时间。

  • auto_now_add:新创建对象时自动添加当前日期时间。

auto_now和auto_now_add和default参数是互斥的,不能同时设置。

DatetimeField

日期时间字段,格式为YYYY-MM-DD HH:MM:ss[.uuuuuu],相当于Python中的datetime.datetime的实例。

TextField

大字符串类型,文本类型

BooleanField

布尔值类型

DecimalField

十进制小数,其中:

  • max_digists设置小数的总长度

  • decimal_places设置的是小数位的长度

更多具体类型

常用字段参数

  • null = True 数据库的该字段可以为空

  • blank = True admin校验时允许输入为空

  • default 设置默认值

  • unique 唯一索引

  • verbose_name admin中显示字段名称

  • choices = ((True,'男'),(False,'女')) Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作

更多字段参数

表的参数Model Meta

 class Person(models.Model):
    pid = models.AutoField(primary_key=True)  # 主键
    name = models.CharField(max_length=32, db_column='username', unique=True, verbose_name='姓名',
                            help_text='填写有效姓名')  # varchar(32)
    age = models.IntegerField(null=True, blank=True)
    birth = models.DateTimeField(auto_now=True)
    phone = MyCharField(max_length=11, null=True, blank=True)
    gender = models.BooleanField(default=True, choices=((True, '男'), (False, '女')))
 class Meta:
    # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
    db_table = "person"
 ​
    # admin中显示的表名称
    verbose_name = '个人信息'
 ​
    # verbose_name加s
    verbose_name_plural = '所有用户信息'
 ​
    # 联合索引
    index_together = [
        ("name", "age"),  # 应为两个存在的字段
    ]
 ​
    # 联合唯一索引
    unique_together = (("name", "age"),)  # 应为两个存在的字段

admin

  1. 创建一个超级用户

     python36 manage.py createsuperuser
     ​
     根据提示输入用户名和密码
     Username (leave blank to use 'aries'): 
     Email address:
     Password:
     Password (again):
     其中密码要求长度至少是8位的字母数字组合
  2. 注册

    在app下的admin.py中进行注册

     from django.contrib import admin
     from app01 import models
     ​
     admin.site.register(models.表名)
  3. 登陆网页http://127.0.0.1:8000/admin/

  4. 找到对应的表做增删改查

字段与参数汇总

  1  AutoField(Field)
  2         - int自增列,必须填入参数 primary_key=True
  3   4  BigAutoField(AutoField)
  5         - bigint自增列,必须填入参数 primary_key=True
  6   7         注:当model中如果没有自增列,则自动会创建一个列名为id的列
  8  【举例】
  9   from django.db import models
 10  11   class UserInfo(models.Model):
 12             # 自动创建一个列名为id的且为自增的整数列
 13             username = models.CharField(max_length=32)
 14  15       class Group(models.Model):
 16             # 自定义自增列
 17           nid = models.AutoField(primary_key=True)
 18           name = models.CharField(max_length=32)
 19  20  SmallIntegerField(IntegerField):
 21         - 小整数 -32768 ~ 32767
 22  23  PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
 24         - 正小整数 0 ~ 32767
 25  26  IntegerField(Field)
 27         - 整数列(有符号的) -2147483648 ~ 2147483647
 28  29  PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
 30         - 正整数 0 ~ 2147483647
 31  32  BigIntegerField(IntegerField):
 33         - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
 34  35  BooleanField(Field)
 36         - 布尔值类型
 37  38  NullBooleanField(Field):
 39         - 可以为空的布尔值
 40  41  CharField(Field)
 42         - 字符类型
 43         - 必须提供max_length参数, max_length表示字符长度
 44  45  TextField(Field)
 46         - 文本类型
 47  48  EmailField(CharField):
 49         - 字符串类型,Django Admin以及ModelForm中提供验证机制
 50  51  IPAddressField(Field)
 52         - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
 53  54  GenericIPAddressField(Field)
 55         - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
 56         - 参数:
 57       protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
 58       unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both"
 59  60  URLField(CharField)
 61         - 字符串类型,Django Admin以及ModelForm中提供验证 URL
 62  63  SlugField(CharField)
 64         - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
 65  66  CommaSeparatedIntegerField(CharField)
 67         - 字符串类型,格式必须为逗号分割的数字
 68  69  UUIDField(Field)
 70         - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
 71  72  FilePathField(Field)
 73         - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
 74         - 参数:
 75                 path,                     文件夹路径
 76                 match=None,               正则匹配
 77                 recursive=False,           递归下面的文件夹
 78                 allow_files=True,         允许文件
 79                 allow_folders=False,       允许文件夹
 80  81  FileField(Field)
 82         - 字符串,路径保存在数据库,文件上传到指定目录
 83         - 参数:
 84             upload_to = ""     上传文件的保存路径
 85             storage = None     存储组件,默认django.core.files.storage.FileSystemStorage
 86  87  ImageField(FileField)
 88         - 字符串,路径保存在数据库,文件上传到指定目录
 89         - 参数:
 90             upload_to = ""     上传文件的保存路径
 91             storage = None     存储组件,默认django.core.files.storage.FileSystemStorage
 92             width_field=None,   上传图片的高度保存的数据库字段名(字符串)
 93             height_field=None   上传图片的宽度保存的数据库字段名(字符串)
 94  95  DateTimeField(DateField)
 96         - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
 97  98  DateField(DateTimeCheckMixin, Field)
 99         - 日期格式     YYYY-MM-DD
100 101  TimeField(DateTimeCheckMixin, Field)
102         - 时间格式     HH:MM[:ss[.uuuuuu]]
103 104  DurationField(Field)
105         - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
106 107  FloatField(Field)
108         - 浮点型
109 110  DecimalField(Field)
111         - 10进制小数
112         - 参数:
113             max_digits,小数总长度
114             decimal_places,小数位长度
115 116  BinaryField(Field)
117         - 二进制类型
118   null               数据库中字段是否可以为空
119     db_column           数据库中字段的列名
120     default             数据库中字段的默认值
121     primary_key         数据库中字段是否为主键
122     db_index           数据库中字段是否可以建立索引
123     unique             数据库中字段是否可以建立唯一索引
124     unique_for_date     数据库中字段【日期】部分是否可以建立唯一索引
125     unique_for_month   数据库中字段【月】部分是否可以建立唯一索引
126     unique_for_year     数据库中字段【年】部分是否可以建立唯一索引
127   
128     verbose_name       Admin中显示的字段名称
129     blank               Admin中是否允许用户输入为空
130     editable           Admin中是否可以编辑
131     help_text           Admin中该字段的提示信息
132     choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
133                         如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
134   
135     error_messages     自定义错误信息(字典类型),从而定制想要显示的错误信息;
136                         字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
137                         如:{'null': "不能为空.", 'invalid': '格式错误'}
138   
139     validators         自定义错误验证(列表类型),从而定制想要的验证规则
140                         from django.core.validators import RegexValidator
141                         from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
142                         MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
143                         如:
144                             test = models.CharField(
145                                 max_length=32,
146                                 error_messages={
147                                     'c1': '优先错信息1',
148                                     'c2': '优先错信息2',
149                                     'c3': '优先错信息3',
150                                 },
151                                 validators=[
152                                     RegexValidator(regex='root_\d+', message='错误了', code='c1'),
153                                     RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'),
154                                     EmailValidator(message='又错误了', code='c3'), ]
155                             )
字段与参数汇总

ORM操作

官方文档

常用操作

  • all() 查询所有结果

  • get(**kwargs) 返回与所给条件向匹配的对象,返回结果有且只有一个,如果满足条件的对象超过一个或者没有符合条件的对象就报错

  • filter(**kwargs) 返回一个包含了所有满足条件的对象的列表,可以为空

  • exclude(**kwargs) 返回一个包含了所有不满足条件的对象的列表

  • values(*field) 返回一个特殊的QuerySet,获取对象的字段和对应的值,是一个可迭代的字典列表;如果没有设置参数,则返回数据库每一行的字段以及对应的值;设置了参数,则返回每一行该字段以及对应的值

  • value_list(*field) 获取对象的字段的值;没有设置参数时,返回每一行的记录;设置参数时,则返回该字段所对应的值

  • order_by(*field) 对查询结果进行排序,可以设置多个参数,当遇到重复情况时从左至右依次生效

  • reverse() 对已排序的结果进行反向,要注意的前提一定是已经排过序的QuerySet对象

  • distinct() 从返回的结果中进行去重;还可以对带参数的values的结果进行去重

  • count() 对返回的对象进行计数

  • first() 返回查询结果的第一个元素,获取不到返回none

  • last() 返回查询结果的最后一个元素,获取不到返回none

  • exists() 判断查询结果是否包含数据,有就返回True,无则返回False

小总结

返回QuerySet对象的操作

all filter exclude values(获得的是以集合为元素的列表) values_list(获得的是以元组为元素的列表) order_by reverse distinct

返回对象

get first last

返回布尔值

exists

返回数字

count

【示例】

 1 import os
 2  3  os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings")
 4  import django
 5  6  django.setup()
 7  8  from app01 import models
 9 10  # all  获取所有的数据  QuerySet  对象列表
11  ret = models.Person.objects.all()
12 13  # get  获取一个满足条件的数据   存在且唯一   对象
14  ret = models.Person.objects.get(pk=1)
15 16  # filter  获取所有满足条件的数据  QuerySet  对象列表
17  ret = models.Person.objects.filter(pk=100)
18 19  # exclude 获取所有不满足条件的数据  QuerySet  对象列表
20  ret = models.Person.objects.exclude(pk=100)
21 22  # order_by  按照字段进行排序  QuerySet  对象列表  默认升序  -降序
23  ret = models.Person.objects.all().order_by('age','-pid')
24 25  # reverse  对一个已经排序QuerySet进行翻转 倒叙
26  ret = models.Person.objects.all().order_by('age','-pid').reverse()
27 28  # values()  获取对象的字段名和字段值   没有参数 所有字段   QuerySet
29  #   有参数 获取指定字段
30  ret= models.Person.objects.all().values('pid','name')
31 32  # values_list()  获取对象的字段值   没有参数 所有字段   QuerySet
33  #   有参数 获取指定字段
34  ret= models.Person.objects.all().values_list('name','pid',)
35 36  # distinct  去重
37  ret = models.Person.objects.values('age').distinct()
38 39  # count()  计数
40  ret = models.Person.objects.all().count()
41 42  # first  last  获取第一个或最后一个元素  获取不到就是none
43  ret = models.Person.objects.all().last()
44 45  # exists  判断数据是否存在  布尔值
46  ret = models.Person.objects.filter(pk=100).exists()
示例

单表查询的双下划线条件

 1  ret = models.Person.objects.filter(pk__gt=1)  # greater than  大于
 2  ret = models.Person.objects.filter(pk__lt=5)  # less than  小于
 3  ret = models.Person.objects.filter(pk__gte=1)  # greater than equal 大于等于
 4  ret = models.Person.objects.filter(pk__lte=5)  # less than  equal  小于等于
 5  6  ret = models.Person.objects.filter(pk__range=[1,5])  # 范围 1到5
 7  8  ret = models.Person.objects.filter(pk__in=[1,5,7,9])  # 范围 
 9 10  ret = models.Person.objects.filter(name__contains='alex')  # like
11  ret = models.Person.objects.filter(name__icontains='aLex')  # like ignore 忽略大小写
12 13  ret = models.Person.objects.filter(name__startswith='a')  # 以什么开头
14  ret = models.Person.objects.filter(name__istartswith='a')  # 以什么开头 ignore 忽略大小写
15 16  ret = models.Person.objects.filter(name__endswith='x')  # 以什么结尾
17  ret = models.Person.objects. filter(name__iendswith='a')  # 以什么结尾 ignore 忽略大小写
18 19  ret = models.Person.objects.filter(birth__year='2020')  # birth字段year是2020
20  ret = models.Person.objects.filter(birth__contains='2020-10')# birth字段含有2020-10的
21 22  ret = models.Person.objects.filter(age__isnull=False)  # age不为空,这里的空指的是为Null的情况,不能判断''空字符串
双下划线条件

猜你喜欢

转载自www.cnblogs.com/jjzz1234/p/11483097.html