Django3.0数据模型Models

Django使用ORM模式创建数据模型(数据表)

  • 每个模型被表示为django.db.models.Model 类的子类
    1
    2
    3
    from django.db import models

    class 模型名/表名(models.Model):
  • 每个字段是Field类的实例,它表示字段类型,如CharField
    • Field类被定义在django.db.models.fields,但出于方便的目的,它们被导入 django.db.models
    • 使用models.<foo>fieldsXXX,来定义字段实例
  • 每个Field类实例的变量名字作为字段名,数据库将它作为列名
1
2
3
4
5
6
7
<!--more-->

from django.db import models


class Student(models.Model):
name = models.CharField(max_length=128)

字段选项

null

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

    blank

  • 如果设置为 True ,该字段允许为空。默认为 False 。请注意,这与 null 不同。Null 完全与数据库相关,而 blank 与验证相关。如果字段具有 blank = True,则表单验证将允许输入空值。如果字段具有 blank = False,则需要该字段。

    choices

  • 值为由列表元组嵌套组成,表示可选值,体现到表单上是一个选择框
  • 每个元组中的第一个元素是要在模型上设置的实际值,第二个元素是人们可读的名称,[(a1,b1),(a2,b2),(a3,b3)….]

    db_column

  • 设置此项则使用此项值作为列名,否则默认使用Field的变量名

    db_index

  • 如果为 True,则将为此字段创建数据库索引。

    default

  • 该字段默认值

    editable

  • 如果为 False,则该字段将不会显示在管理员或任何其他 ModelForm 中。在模型验证期间,它们也被跳过。默认为真。

    error_messages

  • 覆盖字段值引发错误的消息

    help_text

  • 额外的“帮助”文本,随表单控件一同显示。可以在其中使用html

    primary_key

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

    unique

  • 如果设置为 True,这个字段必须在整个表中保持值唯一,不可重复。这是在数据库级别和通过模型验证强制执行的。如果尝试在唯一字段中保存具有重复值的模型,在执行save()方法时,会抛出django.db.IntegrityError错误
  • 注意,当 unique 为 True 时,不需要指定db_index,因为 unique 意味着创建索引。

    unique_for_date

  • 将其设置为 DateField 或 DateTimeField 的名称,以要求该字段对于日期字段的值是唯一的。如:
    1
    2
    3
    4
    5
    6
    from django.db import models

    class Record(models.Model):
    title = CharField(max_length=128,unique_for_date="pub_data")
    pub_date = DateField()
    #不允许输入两个title和 pub _ date 相同的记录

    unique_for_month

  • 类似,略。

    unique_for_year

  • 类似,略。

    unique_for_month

  • 类似,略。

字段类型

AutoField

  • 根据可用 id 自动递增的 IntegerField。您通常不需要直接使用它; 如果您不另行指定,主键字段将自动添加到模型中。

BigAutoField

  • 一个64位的整数,很像一个自动字段,从1到9223372036854775807的数字。

BigIntegerField

  • 一个64位的整数,很像 IntegerField,从-922337203685475808到9223372036854775807。这个字段的默认表单小部件是 NumberInput。

BinaryField

  • 存储原始二进制数据的字段。它可以分配字节、字节数组或存储视图。默认情况下,BinaryField 将 editable 设置为 False,在这种情况下,它不能包含在 ModelForm 中。
  • 额外的可选参数:
    • BinaryField.max_length字段的最大长度(以字符为单位)。
  • 不建议把文件作为BinaryField存储在数据库中,这会极大的影响数据库性能

    BooleanField

  • 布尔数据类型。这个字段的默认窗体小部件是 CheckboxInput,如果 null = True,则为 NullBooleanSelect。

    CharField

  • 字符串类型字段。
    • 对于大量的文本,使用 TextField。
    • 这个字段的默认表单小部件是 TextInput。
  • CharField 有一个额外的必需参数:
    • CharField.max_length 字段的最大长度(以字符为单位)。MaxLengthValidator 在数据库级别和 Django 的验证中强制使用 MaxLengthValidator。

      DateField

  • DateField(auto_now=False, auto_now_add=False, **options * * )
  • 日期类型数据,在 Python 中由 datetime.date 实例表示,有一些额外的可选参数:
  • 额外可选参数
    • DateField.auto_now 每次保存对象时自动将字段设置为 now。适用于”最后修改”时间戳。该字段仅在调用 Model.save ()时自动更新。当以其他方式(如 QuerySet.update ())对其他字段进行更新时,该字段不会更新,不过您可以在这样的更新中为该字段指定自定义值。
    • DateField.auto_now_add首次创建对象时自动将字段设置为 now。有助于创建时间戳。请注意,总是使用当前日期; 它不仅仅是可以覆盖的默认值。因此,即使在创建对象时为该字段设置了值,它也会被忽略。这个字段的默认表单小部件是 DateInput。管理员添加了一个 JavaScript 日历,以及“今天”的快捷方式。包括一个额外的invalid_date error message key。

DateTimeField

  • 日期和时间,在 Python 中由 datetime.datetime 实例表示。
  • 此字段的默认表单小部件是单个 datetimput。管理员使用两个独立的带有 JavaScript 快捷方式的 TextInput 小部件。

DecimalField

  • 一个固定精度的十进制数,用 Python 中的 Decimal 实例表示,它使用 DecimalValidator 验证输入。

  • 有两个必需的参数:

    • DecimalField.max_digits 数字中允许的最大位数。注意,这个数字必须大于或等于小数点后 _ 位。

    • DecimalField.decimal_places 与数字一起存储的小数位数。

  • 例如,要存储高达999的小数点后两位的数字,你可以使用:models.DecimalField(..., max_digits=5, decimal_places=2)

  • 并且以小数点后10位的分辨率存储大约10亿个数字:models.DecimalField(..., max_digits=19, decimal_places=10)

  • 当 localize 为 False 或否则为 TextInput 时,此字段的默认表单小部件是 NumberInput。

EmailField

  • 使用 EmailValidator 检查该值是否为有效电子邮件地址的 CharField。

    FileField

  • FileField(upload_to=None, max_length=100, **options * * )
  • 文件上传字段。

FloatField

  • 由 float 实例在 Python 中表示的浮点数。

    ImageField

    ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options * * )
  • 从 FileField 继承所有属性和方法,但也验证上载的对象是否为有效图像。

IntegerField

  • 整型字段。值从-2147483648到2147483647。

GenericIPAddressField

-GenericIPAddressField(protocol=’both’, unpack_ipv4=False, **options * * 选项)

  • 一个 IPv4或 IPv6地址,字符串格式(例如192.0.2.30或2a02:42fe: : 4)。这个字段的默认表单小部件是 TextInput。
  • 参数解释
    • protocol限制指定协议的有效输入。可接受的值为both(默认值)IPv4IPv6。匹配不区分大小写。
    • unpack_ipv4,默认false。如果启用此选项,IPV6地址将被解压缩为IPV4。只有当协议设置为both时才能使用。

PositiveIntegerField

  • 类似IntegerField,但是为正数。正整型字段,值从0到2147483647。

    PositiveSmallIntegerField

  • 类似PositiveIntegerField,值从0到32767。

    SlugField

  • slug是一个新闻术语。是某物的简短标签,只包含字母、数字、下划线或连字符。它们通常用于url。
  • CharField类似,您可以指定max_length,如果没有指定max_lengthDjango将使用默认长度50。
  • SlugField.allow_unicode如果为 True,则该字段除接受 ASCII 字母外还接受 Unicode 字母。默认值为 False。

SmallAutoField

  • AutoField类似,但只允许在某个(依赖于数据库的)限制下的值。值从1到32767。

SmallIntegerField

  • 类似于IntegerField,但只允许某个(数据库相关)点下的值。值从-32768到32767。

TextField

  • 长文本字段。这个字段的默认表单小部件是一个 Textarea。

  • 如果指定 max _ length属性,它将反映在自动生成表单字段的 Textarea小部件中。但是,它不在模型或数据库级别上强制执行。将使用 CharField替代。

TimeField

  • 时间字段,在 Python 中由 datetime.time 实例表示。接受与 DateField 相同的自动填充选项。

  • 这个字段的默认窗体小部件是 TimeInput,管理员添加一些 JavaScript 快捷方式。

URLField

  • URLField(max_length=200, **options * * )

  • 用于 URL 的 CharField,由 URLValidator验证。这个字段的默认表单小部件是 URLInput。

  • 与所有 CharField子类一样,URLField 采用可选的 max _ length 参数。如果没有指定 max _ length,则使用默认值200。

UUIDField

  • 用于存储普遍唯一标识符的字段。使用 Python 的 UUID 类。在 PostgreSQL 上使用时,它以 uuid 数据类型存储,否则以 char (32)存储。
  • 全局唯一标识符是 AutoField 的一个很好的替代主键。数据库不会为您生成 UUID,因此建议使用默认值:
1
2
3
4
5
6
7
8
9
10

import uuid

from django.db import models



class MyUUIDModel(models.Model):

id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

关联关系

多对一关系ForeignKey

  • models.ForeignKey('self', on_delete=models.CASCADE)

  • 两个必须参数:to此模型字段指向哪个唯一模型 on_delete删除触发不同处理方式

  • 在幕后,Django在该模型中创建一个_id字段来存储关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

from django.db import models



class Student(models.Model):

name = models.CharField(max_length=128)

age = models.SmallIntegerField()

school = models.ForeignKey(to='School', on_delete=models.CASCADE)



class School(models.Model):

name = models.CharField(max_length=128)

address = models.CharField(max_length=256)
  • 解决不同APP之间数据模型循环引用=》抽象模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# products/models.py

from django.db import models



class AbstractCar(models.Model):

# 定义抽象汽车模型,用于桥接

manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)



class Meta:

abstract = True
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# production/models.py

from django.db import models

from products.models import AbstractCar

# 引入另一个APP的模型





class Manufacturer(models.Model):

pass



class Car(AbstractCar):

# 继承另一个APP的模型

pass



# Car.manufacturer =》`production.Manufacturer`

参数解释

  • ForeignKey.on_delete
1
2
3
4
5
6
7
8
9
10

CASCADE 级联删除,删除关联和模型实例

PROTECT 防止删除关系引用的对象,会抛出引发 ProtectedError (django.db. IntegrityError 的一个子类)

SET_NULL 设置ForigenKey为null,必须当前字段设置null=true

SET_DEFAULT 将 ForeignKey 设置为其默认值,必须同时设置`default`

SET() 将 ForeignKey 设置为它接收的参数,可以为具体变量或值,也可以是一个可调用的对象(为了避免导入models.py时执行)
  • ForeignKey.limit_choices_to

    • 在使用 ModelForm 或 admin 呈现该字段时,为该字段的可用选项设置限制(默认情况下,可以选择 queryset 中的所有对象)。可以使用字典或返回字典的可调用对象。

    • 当与 Python datetime 模块一起使用以限制日期范围的选择时,可调用表单可能很有帮助。例如:

1
2
3
4
5
6
7
8

def limit_pub_date_choices():

return {'pub_date__lte': datetime.date.utcnow()}



limit_choices_to = limit_pub_date_choices
  • ForeignKey.related_name

    • 用于从相关对象到这个对象的关系的名称。

    • 相当于相关对象中设置的backwards relation,如果不想创建向后关系,设置related_name='+'

  • ForeignKey.related_query_name

    • 用于从目标模型反向筛选器名称的名称。

    • 例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

class Tag(models.Model):

article = models.ForeignKey(

Article,

on_delete=models.CASCADE,

related_name="tags",

related_query_name="tag",

)

name = models.CharField(max_length=255)





Article.objects.filter(tag__name="important")
  • ForeignKey.to_field

    • ForeignKey.to的更进阶选项,默认情况必须设置to=xxx指向关联模型,被关联模型的主键自动与该字段关联

    • 如设置to_field,则该字段关联至关系模型的指定字段,此字段必须设置unique = True


多对多关系ManyToMany

  • ManyToManyField(to=‘’, **options * * ),必选字段to指向被关联模型

  • 在幕后,Django 创建了一个中间连接表来表示多对多关系。默认情况下,这个表名是使用多对多字段的名称和包含它的模型的表名生成的。

参数

  • ManyToManyField.related_name 与 ForeignKey.related _ name 相同。
  • ManyToManyField.related_query_name 与 ForeignKey.related_query_name 相同。
  • ManyToManyField.limit_choices_to 与 ForeignKey.limit_choices_to选项相同。
  • ManyToManyField.through 默认情况,Django 将自动生成一个表来管理多对多关系。但是,如果您想手动指定中间表,您可以使用 through 选项来指定表示您想要使用的中间表的 Django 模型。
  • ManyToManyField.through_fields 仅在明确给出一个自定义中间模型时使用。django将会正常地的决定使用中间模型的那些字段来自动地建立一个多对多的关系。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

from django.db import models



class Person(models.Model):

name = models.CharField(max_length=50)



class Group(models.Model):

name = models.CharField(max_length=128)

members = models.ManyToManyField(

Person,

through='Membership',

through_fields=('group', 'person'),

)



class Membership(models.Model):

group = models.ForeignKey(Group, on_delete=models.CASCADE)

person = models.ForeignKey(Person, on_delete=models.CASCADE)

inviter = models.ForeignKey(

Person,

on_delete=models.CASCADE,

related_name="membership_invites",

)

invite_reason = models.CharField(max_length=64)

through_fields接受一个2元组(fiels1,fields2),其中fields1是多对多关系字段被定义的那个模型的外键名称,fields2是目标模型的外键名称

  • ManyToManyField.db_table 要创建用于存储多对多数据的表的名称。如果没有提供这个选项,Django 将根据定义关系的模型表的名称和字段本身的名称来假定一个默认名称。

一对一关系 OneToOneField

  • OneToOneField(to, on_delete, parent_link=False, **options)

  • 一对一的关系。从概念上讲,这类似于 unique = True 的 ForeignKey,但是关系的“反向”方将直接返回单个对象。


模型方法

__str__

  • 执行查询语句时,一般返回一个对象<QuerySet [<模型名 模型名 object(1)>]>

  • 设置此方法后,返回值可以设置模型中的字段,更方便的返回对象便于识别。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

请我喝杯咖啡吧~

支付宝
微信