• django中Models常用的字段及属性介绍


    模型类

    介绍

    每个模型类都可以被映射为数据库中的一个数据表,类类属性被映射为数据字段,除此之外,数据库表的主键、外键、约束等也通过类属性完成定义

    模型类属性

    属性描述
    AutoField

    AutoField 字段,一个自动递增的整型字段,添加记录时会自动增长,通常会用于充当数据表的主键。

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

    默认创建的主键列属性名称为id,可以使用pk代替,pk全拼为primary key。注意1:pk是主键的别名,若主键名为id2,那么pk是id2的别名。

    注意2:如果不想django帮你自动创建主键,自己手动创建的话,需要加上primary_key=True,数据库有且只有一个主键

    IntegerField用于保存一个整数
    SmallIntegerField类似于 IntegerField 但只具有较小的输入范围,具体范围依赖于所使用的数据库
    BigIntegerField64位整型字段
    BinaryField二进制数据字段 只能通过 types 对其赋值
    FloatField浮点型字段 定义本字段时必须传入 max_digitsdecimal_places 参数 用于定义总位数(不包括小数点和符号)和小数位数
    DecimalField十进制浮点数 max_digits参数表示总位 decimal_places 参数表示小数位数
    CommaSeparatedIntegerField用于存放逗号分隔的整数值 相较与普通的 CharField, 它有特殊的表单数据验证要求
    DurationField存储时间周期, 用 Python 的 timedelta 类型构建
    EmailField一个带检查 Email 合法性的CharField
    FileField

    用于上传图片,需定义upload_to参数,

    如果路径不存在,会自动创建

    使用本字段需安装pip install pillow图片库;设置upload_to 到某个目录下,

    需要在settings.py中配置多媒体文件路径:

    MEDIA_ROOT = os.path.join(BASE_DIR, "uploads")

    FilePathField按目录限制规则选择文件
    定义本字段必须传入参数 path ,用于限制目录
    ImageField

    用于上传图片并验证图片合法性,需定义upload_to参数,

    如果路径不存在,会自动创建

    使用本字段需安装pip install pillow图片库;设置upload_to 到某个目录下,

    需要在settings.py中配置多媒体文件路径:

    MEDIA_ROOT = MEDIA_ROOT = os.path.join(BASE_DIR, "uploads")

    IPAddressField一个字符串形式的IP地址
    例如: 192.23.250.2
    NullBooleanField类似于 BooleanField, 但比其多一个None选项
    PhoneNumberField带有美国风格的电话号码校验的 CharField
    格式为 XXX-XXX-XXXX
    SlugField只包含字母、数字、下划线和连字符的输入字段
    通常用于URL
    URL用于保存URL
    USStateField美国州名的缩写字段,由两个字母组成
    XMLFieldXML字段
    是具有XML合法验证的TextField
    OneToOneField一对一,本质上就是ForeignKey加unique
    ForeignKey一对多
    ManyToManyField

    多对多(很少是使用,局限性太强,一般手动创建)

    手动创建关系表,再借用through函数绑定到关系表,关系信息的维护仍是手动

    class Book(models.Model):

       title = models.CharField(max_length=32)

    class Author(models.Model):

       name = models.CharField(max_length=32)

       books = models.ManyToManyField(Book, through='Book_Author')

    class Book_Author(models.Model):

       book = models.ForeignKey(Book, on_delete=models.CASCADE)

       author = models.ForeignKey(Author, on_delete=models.CASCADE)

       date = models.DateField()

         

    # 添加关系

    #方式一:

    m1 = BookAuthor(author=author对象,book=book对象)

    #方式二(可以不绑定):

    m2 = BookAuthor.objects,create(author=author对象,book=book对象)

    BooleanField布尔字段
    CharFieldCharField
    TextField大容量文本字段
    DateField

    日期字段  

    auto_now 当对象被保存时,将该字段的值设置为当前时间
    auto_now_add 当对象被首次创建时,将该字段的值设置为当前时间

    DateTimeField(常用此字段)

    类似于 DateField,但同时支持于时间的输入

    auto_now 当对象被保存时,将该字段的值设置为当前时间
    auto_now_add 当对象被首次创建时,将该字段的值设置为当前时间

    TimeField

    时间字段,类似于 DateTimeField
    但只能表达和输入时间

    auto_now 当对象被保存时,将该字段的值设置为当前时间
    auto_now_add 当对象被首次创建时,将该字段的值设置为当前时间

    模型类属性参数

    参数描述
    max_length定义字符的长度,一般用于CharField
    primary_key主键(一个模型只能有一个主键,如果不想手动生成,不需要使用该字段)
    null对于数据库,存入数据库是null
    blank针对于表单验证
    choices定义字段的可选值
    本字段的值应该是一个包含二维元素的元组
    元组的每个元素的第一个值是实际存储的值,
    第二个值是HTML页面进行选择时显示的值
    default默认值
    help_textHTML页面中输入控件的帮助字符串
    unique唯一,如果设置了unique,就不需要设置db_index,因为其就是表示唯一索引
    db_index若值为True,则在表中会为此字段创建索引
    默认False
    db_column字段的名称
    如果未指定,则使用属性的名称

    db_contraint

    表与表仅仅逻辑关联,注意容易出现脏读,

    保留跨表查询的便利(双下划线跨表查询```),但是不用约束字段了

    与null=True, blank=True,on_delete=models.SET_NUL连用才生效

    on_delete

    CASCADE:这就是默认的选项,级联删除。
    PROTECT: 保护模式,如果采用该选项,删除的时候,会抛出ProtectedError错误。
    SET_NUL: 置空模式,删除的时候,外键字段被设置为空,前提就是blank=True, null=True`,定义该字段的时候,允许为空。
    SET_DEFAULT: 置默认值,删除的时候,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。
    SET(): 自定义一个值,该值当然只能是对应的实体了

    limit_choices_to

    限制关联字段的对象范围

    从上面的model字段可以看出, class_teacher字段限制了选择条件:{'depart__title': '教质部'}, 即在选择班主任的时候,只能选择关联班主任的外键表depart中名称为教质部的数据

    ManyToMany字段的limit_choices_to指向了 {'depart__title__in':['xx','xx']} 一个列表,那在前端中只能选择这个列表中的数据

    class ClassList(models.Model):
        """
        班级表
        """
        school = models.ForeignKey(verbose_name='校区', to='School', on_delete=models.CASCADE)
     
      
        class_teacher = models.ForeignKey(verbose_name='班主任', to='UserInfo', related_name='classes',
                                          on_delete=models.CASCADE, limit_choices_to={'depart__title': '教质部'})
        tech_teachers = models.ManyToManyField(verbose_name='任课老师', to='UserInfo', related_name='teach_classes',
                                               limit_choices_to={'depart__title__in': ['Python教学部', 'Linux教学部']})
        memo = models.TextField(verbose_name='说明', null=True, blank=True)

    related_name

    反向查询时用到,就不需要小写表名_set这么复杂了,

    unique_for_date数据库中字段【日期】部分是否可以建立唯一索引
    unique_for_month数据库中字段【月】部分是否可以建立唯一索引
    unique_for_year数据库中字段【年】部分是否可以建立唯一索引
    editableAdmin中是否可以编辑
    validators

    自定义错误验证(列表类型),从而定制想要的验证规则

    from django.core.validators import RegexValidator
    from django.core.validators import EmailValidator,URLValidator,DecimalValidator,
    MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
    如:
    test = models.CharField(
        max_length=32,
        error_messages={
        'c1': '优先错信息1',
        'c2': '优先错信息2',
        'c3': '优先错信息3',
    },
    validators=[
        RegexValidator(regex='root_\d+', message='错误了', code='c1'),
        RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'),
        EmailValidator(message='又错误了', code='c3'), ]
    )

    元选项 (Meta类)

    属性描述
    abstract标识本类是否为抽象基类,如果为抽象基类,将不生成新表,一般做基表用
    True or False
    app_label定义本类所属的应用
    db_table映射的数据库表名,例如: db_table=‘moments’
    如果在Meta中不提供 db_table 字段,则Django 会为模型自动生成数据表名,生成的格式为“应用名_模型名”,例如:应用app的模型UserInfo的默认数据表名为 app_UserInfo
    db_tablespace映射的表空间名称
    表空间的概念只在某些数据库如 Oracle 中存在,不存在表空间的概念的数据库将忽略此字段
    default_related_name定义本模型的反向关系引用名称,默认与模型名一致
    get_latest_by定义按哪个字段值排列以获得模型的开始或结束记录
    本属性值通常指向一个日期或整型的模型字段
    managedTrue or False
    定义 Django的 manage.py 命令行工具是否管理本模型。
    默认为 True,若将其设置为 False,则运行 python manage.py migrate 时将不会在数据库中生成本模型的数据表,所以需要手工维护数据库的定义
    order_with_respect_to定义本模型可以按照某外键引用的关系排序
    order本模型记录的默认排序字段,可以设置多个字段,默认以升序排列,
    若以降序排列则表示要在字段名前加负号("-")
    例如:定义 user_name 字段升序 和 pub_date 降序排列
    order = ['user_name','-pub_date']
    dafault_permissions模型操作权限
    默认为 default_permisstions=('add','change','delete')
    proxyTrue or False
    本模型及所有继承自本模型的子模型是否为代理模型
    required_db_features定义底层数据库所必须具备的特性
    例如:required_db_features=['gis_enabled']只将本数据模型生成在满足 gis_enabled 特性的数据库中
    required_db_vendor定义底层数据库类型
    比如 SQLite,PostgreSQL,MySQL,Oracle
    如果定义了本属性,则模型只能在其声明的数据库中被维护
    unique_together

    用来设置的不重复的字段组合,必须唯一(可以将多个字段做联合唯一)
    例如:unique_together = (("user_name","pub_date"),)
    定义了每个 user_name 在同一个 pub_date 中只能有一条数据表记录
    因为 unique_together 本身是一个元组,所以可以设置多个这样的唯一约束

    注意:django将弃用该字段,推荐在django2.2以上使用UniqueConstraints

    UniqueConstraint

    联合唯一(django2.2以上使用UniqueConstraints)

    class Meta:
        constraints = [
            # 联合唯一
            models.UniqueConstraint(fields=['name', 'title'], name='unique_name')
          
        ]
    index_together定义联合索引的字段,可以设置多个
    例如:index_together = [["pub_date","deadline"],]
    verbose_name

    指明一个易于理解和表述的单数形式的对象名称。

    如果这个值没有被设置,则Django将会使用该model的类型的分词形式作为它的对象表述名,即 CamelCase 将会被转换为camel case

    verbose_name_plural指明一个易于理解和表述的复数形式的对象名称

    proxy

    介绍

    在不动原型的基础上,代你操作完成一些功能。如现需求通过手机号来作为验证条件,那就得增加字段,扩展用户模型了。

    代理模型不会改变原数据,只是在原有的基础上增加一些方法,使其更完善,代理不能添加字段,只能增加操作方法。

    Proxy模型

    1. from django.db import models
    2. #导入自带的用户模型,给代理继承
    3. from django.contrib.auth.models import User
    4. from django.core import validators
    5. # 定义一个Person类代理继承自User
    6. class Person(User):
    7. telephone = models.CharField(max_length=11,validators=[validators.RegexValidator(r'1[3-9]\d{9}',message='请输入正确的手机号')])
    8. #在Meta中设置proxy=True,表示不会影响原数据结构
    9. class Meta:
    10. #说明Person是User的代理类
    11. proxy = True

    比如想要获取黑名单,取决于表中的is_active

    如果想方便的获取所有黑名单的人,那么就可以通过,Person.get_blacklist()就可以获取到。并且User.object.all()和Person.objects.all()是等价的。

    因为都是从User这个模型中获取所有的数据。

    1. class Person(User):
    2. telephone = models.CharField(max_length=11,validators=[validators.RegexValidator(r'1[3-9]\d{9}',message='请输入正确的手机号')])
    3. class Meta:
    4. #说明Person是User的代理类
    5. proxy = True
    6. # 获取黑名单 来源取决active
    7. @classmethod
    8. def get_blacklist(self):
    9. return self.objects.filter(is_active=False)

    CheckConstraint(条件约束)

    条件约束确保一个模型实例只有满足一定的规则条件后才被创建,不满足条件的数据不会存入到数据库。下例增加了一个对员工年龄的约束,只有大于18岁的才能注册。

    1. from django.db import models
    2. # Create your models here.
    3. class Text_one(models.Model):
    4. title = models.CharField(max_length=225)
    5. name = models.CharField(max_length=225, db_index=True)
    6. count = models.IntegerField(default=100)
    7. class Meta:
    8. constraints = [
    9. # count大于18才能保存
    10. models.CheckConstraint(check=models.Q(count__gte=18), name='age__gte_18')
    11. ]

    其他操作

    模型中自定义图片和文件上传路径

    Django模型中的ImageField和FileField的upload_to选项是必填项,其存储路径是相对于MEIDA_ROOT而来的。然而我们可能希望动态定义上传路径,比如把文件上传到每个用户名下的文件夹里,并对上传文件重命名,这时我们可以定义一个user_directory_path方法。

    1. from django.db import models
    2. from django.contrib.auth.models import User
    3. import uuid
    4. import os
    5. # Create your models here.
    6. def user_directory_path(instance, filename):
    7. ext = filename.split('.')[-1]
    8. filename = '{}.{}'.format(uuid.uuid4().hex[:10], ext)
    9. # return the whole path to the file
    10. return os.path.join(instance.user.id, "avatar", filename)
    11. class UserProfile(models.Model):
    12. user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    13. avatar = models.ImageField(upload_to=user_directory_path, verbose_name="头像")

    Django模型的Manager方法

    Django模型自带models.Manager方法,可以简化我们的代码。如下面案例中,我们可以使用Person.objects.all()查询到所有人,而Person.authors.all和Person.editors.all()只返回所authors和editors。

    1. class AuthorManager(models.Manager):
    2. def get_queryset(self):
    3. return super().get_queryset().filter(role='A')
    4. class EditorManager(models.Manager):
    5. def get_queryset(self):
    6. return super().get_queryset().filter(role='E')
    7. class Person(models.Model):
    8. first_name = models.CharField(max_length=50)
    9. last_name = models.CharField(max_length=50)
    10. role = models.CharField(max_length=1, choices=(('A', _('Author')), ('E', _('Editor'))))
    11. objects = models.Manager()
    12. authors = AuthorManager()
    13. editors = EditorManager()

    Django模型的save方法重写

    在很多应用场景中我们需要重写django模型的save方法,比如本例中我们希望根据title生成slug,并在一个对象数据save完成后做其它事情(比如发送邮件或发送信号),我们可以按如下代码重写django模型的save方法,非常容易。

    1. from django.template.defaultfilters import slugify
    2. class Article(models.Model):
    3. ...
    4. def save(self, *args, **kwargs):
    5. if not self.slug or not self.id:
    6. self.slug = slugify(self.title)
    7. super().save(*args, **kwargs)

    Django高级模型结构示例

    1. from django.db import models
    2. from django.urls import reverse
    3. # 自定义Manager方法
    4. class HighRatingManager(models.Manager):
    5. def get_queryset(self):
    6. return super().get_queryset().filter(rating='1')
    7. class Product(models.Model):
    8. # CHOICES选项
    9. RATING_CHOICES = (
    10. ("1", 'Very good'),
    11. ("2", 'Good'),
    12. ("3", 'Bad'),
    13. )
    14. # 数据表字段
    15. name = models.CharField('name', max_length=30)
    16. rating = models.CharField(max_length=1, choices=RATING_CHOICES)
    17. # MANAGERS方法
    18. objects = models.Manager()
    19. high_rating_products =HighRatingManager()
    20. # META类选项
    21. class Meta:
    22. verbose_name = 'product'
    23. verbose_name_plural = 'products'
    24. # __str__方法
    25. def __str__(self):
    26. return self.name
    27. # 重写save方法
    28. def save(self, *args, **kwargs):
    29. do_something()
    30. super().save(*args, **kwargs)
    31. do_something_else()
    32. # 定义绝对路径
    33. def get_absolute_url(self):
    34. return reverse('product_details', kwargs={'pk': self.id})
    35. # 定义其它方法
    36. def do_something(self):

    参考文章

    (20条消息) Django-模型model及属性_帅的一库的博客-CSDN博客_django models 属性https://blog.csdn.net/screenswindow/article/details/110222227(20条消息) Django--(2)模型(Model)属性与参数整理_Mikowoo007的博客-CSDN博客_django model 参数https://blog.csdn.net/Mikowoo007/article/details/98203653Django基础篇 03- Models的属性与字段 - 捞铁 - 博客园 (cnblogs.com)https://www.cnblogs.com/hehaheha/p/15221083.html(20条消息) Python之django框架模型(models)详解_嫣夜来的博客-CSDN博客_models pythonhttps://blog.csdn.net/qq_41865652/article/details/106332865?utm_source=app&app_version=5.2.1&code=app_1562916241&uLinkId=usr1mkqgl919blenDjango-ORM之ManyToManyField的使用-多对多关系 - Aries-X - 博客园 (cnblogs.com)https://www.cnblogs.com/jjzz1234/p/11607940.html

         (69条消息) djnago---外键的一些操作_骑台风走的博客-CSDN博客https://blog.csdn.net/qq_52385631/article/details/122851343?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166348141116782248582531%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=166348141116782248582531&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-122851343-null-null.nonecase&utm_term=%E7%BA%A7%E8%81%94&spm=1018.2226.3001.4450

  • 相关阅读:
    使用vue-cli搭建SPA项目
    差分
    包含漏洞-读写文件以及执行命令
    MySQL 和 MariaDB 版本管理的历史背景及差异
    React-Router源码分析-History库
    OSPF邻居关系建立故障排除
    win11恢复win10形式的右键显示
    工具 | Windows 功能猎手 (WFH)
    ent M2M模型在pxc集群中的一个大坑
    Hadoop运行模式
  • 原文地址:https://blog.csdn.net/qq_52385631/article/details/126912695