首页 笔记正文

【笔记】Django ORM中常用字段和参数

從出茳湖 笔记 2019-09-20 68 0

常用字段

常见字段

AutoField

int自增列,必须填入参数primary_key=True。当model中如果没有自增列,则会自动创建一个列名为id的列。

IntegerField

一个整数类型,范围在-214748368to214748367。(一般不用它来存手机号,位数也不够,直接用字符串存)

CharField

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

这里需要知道的是Django中的CharField对应的MySQL数据库中的varchar类型,没有设置对应char类型的字段,但是Django允许我们自定义新的字段,下面我们来自定义对应于数据库的char类型

1.png

EmailField()

varchar(254)内部是个varchar字段

BooleanField(Field)

is_delete = BooleanField()

给该字段传值的时候 你只需要传布尔值即可

但是对应到数据库  它存的是0和1

TextField(Field)

- 文本类型

用来存大段文本

FileField(Field)

- 字符串,路径保存在数据库,文件上传到指定目录

- 参数:

    upload_to = ""      用户上传的文件会自动放到等号后面指定的文件路径中

    storage = None      存储组件,默django.core.files.storage.FileSystemStorage

自定义char字段

from django.db import models

# Create your models here.
#Django中没有对应的char类型字段,但是我们可以自己创建
class FixCharField(models.Field):
    '''
    自定义的char类型的字段类
    '''
    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):
        '''
        限定生成的数据库表字段类型char,长度为max_length指定的值
        :param connection:
        :return:
        '''
        return 'char(%s)'%self.max_length
#应用上面自定义的char类型
class Class(models.Model):
    id=models.AutoField(primary_key=True)
    title=models.CharField(max_length=32)
    class_name=FixCharField(max_length=16)
    gender_choice=((1,'男'),(2,'女'),(3,'保密'))
    gender=models.SmallIntegerField(choices=gender_choice,default=3)

DateField

日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。

DateTimeField

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

字段合集

AutoField(Field)
    - int自增列,必须填入参数 primary_key=True

BigAutoField(AutoField)
    - bigint自增列,必须填入参数 primary_key=True

    注:当model中如果没有自增列,则自动会创建一个列名为id的列
    from django.db import models

    class UserInfo(models.Model):
        # 自动创建一个列名为id的且为自增的整数列
        username = models.CharField(max_length=32)

    class Group(models.Model):
        # 自定义自增列
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)

SmallIntegerField(IntegerField):
    - 小整数 -32768 ~ 32767

PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
    - 正小整数 0 ~ 32767
IntegerField(Field)
    - 整数列(有符号的) -2147483648 ~ 2147483647

PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
    - 正整数 0 ~ 2147483647

BigIntegerField(IntegerField):
    - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807

BooleanField(Field)
    - 布尔值类型

NullBooleanField(Field):
    - 可以为空的布尔值

CharField(Field)
    - 字符类型
    - 必须提供max_length参数, max_length表示字符长度

TextField(Field)
    - 文本类型

EmailField(CharField):
    - 字符串类型,Django Admin以及ModelForm中提供验证机制

IPAddressField(Field)
    - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制

GenericIPAddressField(Field)
    - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
    - 参数:
        protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
        unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both"

URLField(CharField)
    - 字符串类型,Django Admin以及ModelForm中提供验证 URL

SlugField(CharField)
    - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)

CommaSeparatedIntegerField(CharField)
    - 字符串类型,格式必须为逗号分割的数字

UUIDField(Field)
    - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证

FilePathField(Field)
    - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
    - 参数:
        path,         文件夹路径
        match=None,      正则匹配
        recursive=False,    递归下面的文件夹
        allow_files=True,   允许文件
        allow_folders=False,  允许文件夹

FileField(Field)
    - 字符串,路径保存在数据库,文件上传到指定目录
    - 参数:
        upload_to = ""    上传文件的保存路径
        storage = None    存储组件,默认django.core.files.storage.FileSystemStorage

ImageField(FileField)
    - 字符串,路径保存在数据库,文件上传到指定目录
    - 参数:
        upload_to = ""    上传文件的保存路径
        storage = None    存储组件,默认django.core.files.storage.FileSystemStorage
        width_field=None,   上传图片的高度保存的数据库字段名(字符串)
        height_field=None   上传图片的宽度保存的数据库字段名(字符串)

DateTimeField(DateField)
    - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

DateField(DateTimeCheckMixin, Field)
    - 日期格式      YYYY-MM-DD

TimeField(DateTimeCheckMixin, Field)
    - 时间格式      HH:MM[:ss[.uuuuuu]]

DurationField(Field)
  - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型

FloatField(Field)
    - 浮点型

DecimalField(Field)
    - 10进制小数
    - 参数:
        max_digits,小数总长度
        decimal_places,小数位长度

BinaryField(Field)
    - 二进制类型

ORM字段与MySQL字段对应关系

对应关系:
    'AutoField': 'integer AUTO_INCREMENT',
    'BigAutoField': 'bigint AUTO_INCREMENT',
    'BinaryField': 'longblob',
    'BooleanField': 'bool',
    'CharField': 'varchar(%(max_length)s)',
    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
    'DateField': 'date',
    'DateTimeField': 'datetime',
    'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
    'DurationField': 'bigint',
    'FileField': 'varchar(%(max_length)s)',
    'FilePathField': 'varchar(%(max_length)s)',
    'FloatField': 'double precision',
    'IntegerField': 'integer',
    'BigIntegerField': 'bigint',
    'IPAddressField': 'char(15)',
    'GenericIPAddressField': 'char(39)',
    'NullBooleanField': 'bool',
    'OneToOneField': 'integer',
    'PositiveIntegerField': 'integer UNSIGNED',
    'PositiveSmallIntegerField': 'smallint UNSIGNED',
    'SlugField': 'varchar(%(max_length)s)',
    'SmallIntegerField': 'smallint',
    'TextField': 'longtext',
    'TimeField': 'time',
    'UUIDField': 'char(32)',

字段参数

null                         用于表示某个字段可以为空。

unique                    如果设置为unique=True 则该字段在此表中必须是唯一的。

db_index                如果db_index=True则代表着为此字段设置索引。

default

为该字段设置默认值

DateField和DateTimeField

auto_now_add

配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。

auto_now

配置上auto_now=True,每次更新数据记录的时候会自动更新改字段。

关系字段

ForeignKey

外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多'中'多'的一方。

ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系。

字段参数

to                                   设置要关联的表

to_field                          设置要关联的表的字段

on_delete                      当删除关联表中的数据时,当前表与其关联的行的行为。

models.CASCADE        删除关联数据,与之关联也删除

db_constraint              是否在数据库中创建外键约束,默认为True。

其他字段                                                                                                                        

models.DO_NOTHING  删除关联数据,引发错误IntegrityError

models.PROTECT          删除关联数据,引发错误ProtectedError

models.SET_NULL         删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)

models.SET_DEFAULT   删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)

models.SET                   删除关联数据,

a. 与之关联的值设置为指定值,设置:models.SET(值)

b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

def func():    return 10class MyModel(models.Model):
    user = models.ForeignKey(
        to="User",
        to_field="id",
        on_delete=models.SET(func)
    )

OneToOneField

一对一字段。

通常一对一字段用来扩展已有字段。(通俗的说就是一个人的所有信息不是放在一张表里面的,简单的信息一张表,隐私的信息另一张表,之间通过一对一外键关联)

字段参数

to                 设置要关联的表。

to_field        设置要关联的字段。

on_delete    当删除关联表中的数据时,当前表与其关联的行的行为。(参考上面的例子)

ManyToManyField

class RelatedManager

"关联管理器"是在一对多或者多对多的关联上下文中使用的管理器。

它存在于下面两种情况:

1.外键关系的反向查询

2.多对多关联关系

简单来说就是在多对多表关系并且这一张多对多的关系表是有Django自动帮你建的情况下,下面的方法才可使用。

数据库查询优化

only与defer

orm内所有的语句操作都是惰性查询:

只会在你真正需要数据的时候才会走数据库,如果你单单只写orm语句时不会走数据库的

这样设计的好处在于减轻数据库的压力

res = models.Book.objects.all()  # 这一步不查询数据库,惰性查询
print(res)  # 查询数据库
# 例:我们想拿到所有书籍的书名
res = models.Book.objects.values('title')  # 这一步不查询数据库 .values返回的是一个列表套字典
for i in res :
    print(i.title)  #字典没有点取值方法报错
# 我们想通过点取值的方法取所有书名,就需要用到only
res = models.Book.objects.only('title')
for r in res:
    print(r.title)  # 只走一次数据库查询
    print(r.price)  # 每循环一次走一次数据库查询,频繁查询
"""
only会将括号内的所有的字段信息封装成一个对象,支持点取值
当点only括号内指定的字段取值时,只走一次查询,
当点only括号外其他的字段取值时,不会报错,会频繁走数据库查询
"""
# defer与only相反
res = models.Book.objects.defer('title')
for r in res1:
    print(r.price)
"""
defer会将不是括号内的所有的字段信息封装成一个对象,支持点取值
当点defer括号内指定的字段取值时,会频繁走数据库查询
当点defer括号外其他的字段取值时,只走一次查询
"""

select_related与prefetch_related

select_related帮你直接连表操作 查询数据   括号内只能放外键字段

res = models.Book.objects.all()
for r in res:
    print(r.publish.name)  # 每for循环一次跨表一次走一次数据库,效率低

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)
"""
select_related:会将括号内外键字段所关联的那张表  直接全部拿过来(可以一次性拿多张表)跟当前表拼接操作
从而降低你跨表查询 数据库的压力
注意select_related括号只能放外键字段(一对一和一对多)
res = models.Book.objects.all().select_related('外键字段1__外键字段2__外键字段3__外键字段4')
"""

prefetch_related  不主动连表

res = models.Book.objects.prefetch_related('publish')
for r in res:
    print(r.publish.name)
"""
不主动连表操作(但是内部给你的感觉像是连表操作了)
而是将book表中的publish全部拿出来
在取publish表中将id对应的所有的数据取出
res = models.Book.objects.prefetch_related('publish')
括号内有几个外键字段 就会走几次数据库查询操作    
"""

select_related需要连表,虽然跨表只走一次数据库操作,但是连表需要时间,速度慢

prefetch_related不需要连表,每次都只需要两次查询,先查一张表,然后拿着这个表查的数据再查另一张表,内部做了一次拼接,感觉像是连表

事务

事务的定义:将多个sql语句操作变成原子性操作,要么同时成功,有一个失败则里面回滚到原来的状态,保证数据的完整性和一致性(NoSQL数据库对于事务则是部分支持)

ACID

原子性

一致性

隔离性

持久性

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


本文标题:【笔记】Django ORM中常用字段和参数
本文链接:https://zhong-er.com/post/82.html
作者授权:除特别说明外,本文由 從出茳湖 原创编译并授权 中二青年 刊载发布。
版权声明:本文使用「署名-非商业性使用-相同方式共享 4.0 国际」创作共享协议,转载或使用请遵守署名协议。

评论

本站会员尊享VIP特权,现在就加入我们吧!登录注册
登录
用户名
密码
注册
用户名
密码
确认密码
邮箱
获取邀请码
邀请码
验证码
找回密码
用户名
邮箱
※ 重置链接将发送到邮箱