Django教程 —— 模型类详解

引言

在之前的 Django模型设计 中简单的介绍了如何定义模型类,在这篇中将做一个汇总。让大家更加了解Django模型类。


环境

环境名称版本
Python3.9
Django3.1.2
MySql-Server5.7.32
PyMySQL0.10.1

模型类的特性

Django 模型类会根据属性的类型确定以下信息:

  • 当前选择的数据库支持字段的类型
  • 渲染管理表单时使用的默认html控件
  • 在管理站点最低限度的验证

Django 会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后 Django 不会再创建自动增长的主键列。

默认创建的主键列属性为 id,可以使用 pk 代替,pk 全拼为 primary key

注意:pk是主键的别名,若主键名为id2,那么pk是id2的别名。

例如:当编写 Django 查询时,可以使用 id or pk作为查询参数。

Object.objects.get(id=1)
Object.objects.get(pk=1)

pk 代表主键(primary key),pk 更加独立于实际的主键字段,即您不必关心主键字段是否被称为 idobject_id 或任何。如果具有不同主键字段的模型,它还可以提高您的一致性。


模型类的字段属性及选项

模型类属性命名限制

  • 不能是python的保留关键字。
  • 不允许使用连续的下划线,这是由 Django 的查询方式决定的,在第4节会详细讲解查询。
  • 定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
属性 = models.字段类型(选项)

模型类的字段类型

使用时需要引入django.db.models

from django.db import models

字段类型如下:

AutoField

自动增长的 IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性。


BooleanField

布尔字段,值为 TrueFalse


NullBooleanField

支持Null、True、False三种值。


CharField

CharField(max_length=字符长度):字符串。参数 max_length 必须设置,表示最大字符个数。


TextField

大文本字段,一般超过 4000 个字符时使用。


IntegerField

IntegerField:整数类型字段


DecimalField

DecimalField(max_digits=None, decimal_places=None):十进制浮点数。

  • 参数 max_digits 必须设置,表示总位数。

  • 参数 decimal_places 必须设置, 表示小数位数。


FloatField

FloatField:浮点数类型字段。


DateField

DateField([auto_now=False, auto_now_add=False]):日期。

  • 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false。
  • 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false。
  • 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误。

TimeField

TimeField:时间,参数同 DateField


DateTimeField

DateTimeField:日期时间,参数同DateField。


FileField

FileField:上传文件字段


ImageField

ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片。


BinaryField

存储原始二进制数据的字段


EmailField

邮箱字段,字符串类型,会进行邮箱校验


URLField

字符串类型,会进行URL地址校验


FloatField

浮点数类型字段


更多的字段类型请参考 Django 官方文档 https://docs.djangoproject.com/zh-hans/3.1/ref/models/fields/


字段选项

通过选项实现对字段的约束,选项如下:

选项备注
null如果为True,表示允许为空,默认值是False。
blank如果为True,则该字段允许为空白,默认值是False。
db_column字段的名称,如果未指定,则使用属性的名称。
db_index若值为True, 则在表中会为此字段创建索引,默认值是False。
default默认值。
primary_key若为True,则该字段会成为模型的主键字段,默认值是False。
unique如果为True, 这个字段在表中必须有唯一值,默认值是False。
verbose_name详细名称,就是起一个更可读的名字
choices对模型字段选择的枚举。
editablebool 类型,在Admin里是否可编辑,
help_textAdmin 中提示帮助信息
upload_to指文件上传到哪个位置

null 是数据库范畴的概念,blank 是表单验证范畴的

当修改模型类之后,如果添加的选项不影响表的结构,则不需要重新做迁移,属性的选项中 defaultblank 不影响表结构。


Django 3 之前一般会通过定义一些 常量元组 来定义 choices,如下所示:

from django.db import models
 
class Book(models.Model):
    UNPUBLISHED = 'UN'
    PUBLISHED = 'PB'
    STATUS_CHOICES = [
        (UNPUBLISHED, 'Unpublished'),
        (PUBLISHED, 'Published'),
    ]
    status = models.CharField(
        max_length=2,
        choices=STATUS_CHOICES,
        default=UNPUBLISHED,
    )

然后可以按如下方式使用这些常量,例如:

unpub_books = Book.objects.filter(status=Book.UNPUBLISHED)

然而 Django 3 之后建议使用 Field.choices 枚举类型定义 choices 选项

Django 3 现在提供了一个Choices类及其两个子类IntegerChoicesTextChoices 。这些类扩展了Python的 Enum 类型,并增加了额外的约束和功能,以使其适用于 Field.choices

from django.db import models
 
 
class Book(models.Model):
    class Status(models.TextChoices):
    	UNPUBLISHED = 'UN', 'Unpublished'
    	PUBLISHED = 'PB', 'Published'
        
    status = models.CharField(
        max_length=2,
        choices=Status.choices,
        default=Status.UNPUBLISHED,
    )
    

QuerySet 过滤器可以更新为使用以下 Choices 类:

unpublished_books = Book.objects.filter(status=Book.Status.UNPUBLISHED)

模型关系

关系定义备注
一对多models.ForignKey()外键约束 ,定义在 ‘多类’
多对多models.ManyToManyField()定义在哪一个模型类中都行
一对一models.OneToOneField()定义在哪一个模型类中都行
from django.db import models


class BookInfo(models.Model):
    """图书模型类"""

    title = models.CharField(verbose_name=u'图书名称', max_length=20)

    author = models.CharField(verbose_name=u'图书作者', max_length=20)

    pub_date = models.DateField(verbose_name=u'出版日期')

    book_type = models.ForeignKey(BookType, on_delete=models.CASCADE, verbose_name=u'图书类型')

元选项

在模型类中定义类 Meta,用于设置元信息,如使用 db_table 自定义表的名字。

数据表的默认名称为:

<app_name>_<model_name>
例:
booktest_bookinfo

例如:在 BookInfo 模型类中添加如下内容,代码如下:

from django.db import models


class BookInfo(models.Model):
    """图书模型类"""

    title = models.CharField(verbose_name=u'图书名称', max_length=20)

    author = models.CharField(verbose_name=u'图书作者', max_length=20)

    pub_date = models.DateField(verbose_name=u'出版日期')

    book_type = models.ForeignKey(BookType, on_delete=models.CASCADE, verbose_name=u'图书类型')

    def __str__(self):
        return self.title

    class Meta:
        db_table = 'BookInfo'		# 表名称
        
        verbose_name = u'图书信息'	 # 表备注
        
        # 表名复数形式,如果不设置末尾会多一个s
        verbose_name_plural = verbose_name
        
        ordering = ['id']			# 排序字段
        

公众号

新建文件夹X

大自然用数百亿年创造出我们现实世界,而程序员用几百年创造出一个完全不同的虚拟世界。我们用键盘敲出一砖一瓦,用大脑构建一切。人们把1000视为权威,我们反其道行之,捍卫1024的地位。我们不是键盘侠,我们只是平凡世界中不凡的缔造者 。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值