从零开始的Linux运维屌丝之路,资源免费分享平台   运维人员首选:简单、易用、高效、安全、稳定、社区活跃的开源软件

Django中ORM介绍和字段及字段参数

发布:蔺要红07-26分类: Python


ORM的优势

 

ORM解决的主要问题是对象和关系的映射。它通常把一个类和一个表一一对应,类的每个实例对应表中的一条记录,类的每个属性对应表中的每个字段。 
ORM提供了对数据库的映射,不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。
让软件开发人员专注于业务逻辑的处理,提高了开发效率。


ORM的劣势

 

ORM的缺点是会在一定程度上牺牲程序的执行效率。
ORM用多了SQL语句就不会写了,关系数据库相关技能退化

 

Model

 

在Django中model是你数据的单一、明确的信息来源。它包含了你存储的数据的重要字段和行为。通常,一个模型(model)映射到一个数据库表,

基本情况:
 

每个模型都是一个Python类,它是django.db.models.Model的子类。
模型的每个属性都代表一个数据库字段。
综上所述,Django为您提供了一个自动生成的数据库访问API,详询 官方文档链接


ForeignKey(to="Publisher",related_name="xxxx")  # 1对多, 外键通常设置在多的那一边
ManyToManyField(to="Book",related_name="xxxx")   # 多对多 通常设置在正向查询多的那一边

---------------------------django 模型models 常用字段--------------------------
 
1、models.AutoField  
        自增列 = int(1) ,
        如果没有的话,默认会生成一个名称为 id 的列
        如果要显式的自定义一个自增列,必须设置primary_key=True。

2、models.CharField  
       字符串字段
       必须设置 max_length 参数  max_length表示字符长度
  
3、models.ForeignKey 外键
        publisher = models.ForeignKey(to="Publisher")

4、ManyToManyField 多对多关联

5、models.IntegerField  
       整数类型
       一个整数类型,范围在 -2147483648 to 2147483647

6、models.DateField
        日期类型 date
        日期格式  YYYY-MM-DD,相当于Python中的datetime.date()实例
        配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
        配置上auto_now=True,每次更新数据记录的时候会更新该字段

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

8、DecimalField(Field)
        - 10进制小数
        - 参数:
            max_digits,小数总长度
            decimal_places,小数位长度
  
ORM的字段总结
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)
        - 文本类型

    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)
        - 浮点型

    BinaryField(Field)
        - 二进制类型

自定义的char类型的字段类
#---------------------------自定义的char类型的字段类---------------------------
class FixedCharField(models.Field):

    def __init__(self, max_length, *args, **kwargs):
        super().__init__(max_length=max_length, *args, **kwargs)
        self.length = max_length

    def db_type(self, connection):
        """
        限定生成数据库表的字段类型为char,长度为length指定的值
        """
        return 'char(%s)' % self.length

class Class(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=25)
    # 使用上面自定义的char类型的字段
    cname = FixedCharField(max_length=25)

# 效果 有varchar类型和char类型

MySQL [myweb]> desc appweb_class;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| title | varchar(25) | NO   |     | NULL    |                |
| cname | char(25)    | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

ORM的字段参数
 
null=False              如果是True,Django会在数据库中将此字段的值置为NULL,默认值是False
unique=True          不允许重复
primary_key = False    主键,对AutoField设置主键后,就会代替原来的自增 id 列
max_length             字段长度 max_length=64
db_index = True      数据库索引
default                默认值
auto_now               自动创建---无论添加或修改,都是当前操作的时间
auto_now_add          自动创建---永远是创建时的时间
verbose_name         Admin中字段的显示名称,如果不设置该参数时,则与属性名。
db_column            数据库中的字段名称
editable=True        在Admin里是否可编辑
error_messages=None  错误提示
auto_created=False    自动创建
help_text            在Admin中提示帮助信息
validators=[]          验证器
upload-to              文件上传时的保存上传文件的目录
blank   如果为True时django的 Admin中添加数据时可允许空值,可以不填,如果为False则必须填,默认是False。
        null纯粹是与数据库有关系的。而blank是与页面必填项验证有关的
choices
      一个二维的元组被用作choices,如果这样定义,Django会select box代替普通的文本框,
      并且限定choices的值是元组中的值
      GENDER_CHOICE = (
            (u'M', u'Male'),
            (u'F', u'Female'),
      )
      gender = models.CharField(max_length=2,choices = GENDER_CHOICE)

ORM的练习
 
from django.db import models
class Userinfo(models.Model):
    id = models.AutoField(primary_key=True) #创建一个自增的主键
    name = models.CharField(null=False,max_length=20,unique=True)    #创建一个varchar(可以保存可变长度的字符串)类型不能为空
    def __str__(self):
        return "<{} {}>".format(self.id,self.name)
    '''
    定义如下:代表自定义表名字不加前缀:库中表名就为 userinfo
    class Meta:
        db_table = "userinfo"
    如果不定义 class Meta 库中表名则为 appweb_userinfo
    '''

class Publisher(models.Model):
    id = models.AutoField(primary_key=True) #创建一个自增的主键
    # unique 唯一的不为空的字段
    name = models.CharField(null=False,max_length=64,unique=True)  #创建一个varchar(可以保存可变长度的字符串)类型不能为空
    addr = models.CharField(max_length=128)
    def __str__(self):
        return "<{} {}>".format(self.id,self.name)
    
class Book(models.Model):
    id = models.AutoField(primary_key=True)#自增的住建
    title = models.CharField(max_length=64,null=False,unique=True)
    #ForeignKey表示外键
    publisher = models.ForeignKey(to="Publisher",on_delete=models.CASCADE,related_name="books")
    # 这里创建的字段为publisher_id (Django会自动加_id)所以不用写成publisher_id否者就变成了publisher_id_id
    '''
    
    related_name="books" #反向查询的时候可是用books来代替book_set的查询方式
    
    on_delete=models.CASCADE #默认就是这种方式  2.0需要指定
    db_constraint=False #不在数据库层建立约束,通过代码控制  默认是True
    大数据下不用外键,使用代码约束,使用外键分库分表很难
    models.CASCADE       删除关联数据,与之关联也删除
    models.DO_NOTHING    删除关联数据,引发错误IntegrityError
    models.PROTECT       删除关联数据,引发错误ProtectedError
    models.SET_NULL      删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
    models.SET_DEFAULT   删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
    publisher = models.ForeignKey(to="Publisher")  #  如果出版社被删除、则书籍也被删除
    '''
    def __str__(self):
        # 两种写法
        return "Book object :%s" %self.title  # 必须返回str
        # return "<Book Object: {}>".format(self.title)
class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(null=False,max_length=16,unique=True)
    # 告诉ORM 这张表和book表是多对多的关系,ORM自动生成第三章表
    book = models.ManyToManyField(to="Book")
    def __str__(self):
        return "<Author Object: {}>".format(self.name)
class Person(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField(default=18)
    birthday = models.DateField(auto_now_add=True)
class Assets(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64,unique=True,null=False)
    number = models.IntegerField(unique=True,null=False)
    network_ip = models.GenericIPAddressField(unique=True,null=False)
    add_time = models.DateField(auto_now_add=True)
    update_time = models.DateField(auto_now=True)
    def __str__(self):
        return "{}{}{}{}".format(self.id,self.name,self.network_ip,self.add_time)
温馨提示如有转载或引用以上内容之必要,敬请将本文链接作为出处标注,如有侵权我会在24小时之内删除!

欢迎使用手机扫描访问本站