Django 模型

模型基础

模型是关于数据的惟一的、肯定的信息源。它包含您正在存储的数据的基本字段和行为。一般,每一个模型映射到一个数据库表。python

基础:git

  1. 模型是一个继承django.db.models.Model的class类
  2. 每一个属性对应一个数据库字段
  3. django提供了一个自动生成的数据库访问API

例子:算法

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

生成数据库文件sql

CREATE TABLE myapp_person (
    "id" serial NOT NULL PRIMARY KEY,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL
);

注:table名是django自动添加的(可自定义) id是django自动添加的(可自定义) SQL语句是django自动生成的,可针对不一样的数据库进行迁移数据库

当迁移models时,须要在INSTALLED_APPS中注册当前appdjango

迁移指令:app

python manage.py makemigrations myAPP
python manage.py sqlmigrate myAPP
python manage.py migrate

Filed

模型最重要的部分就是字段,避免字段名字与models API名相同框架

Filed Types

每一个字段都必须是Field类的实例,Django使用filed类来描述一些信息:函数

  1. column type 告诉数据库数据的类型(int,varchar,text...)
  2. widget 自动生成的form表单类型(<input type="text">)
  3. 由Django管理和自动生成表单的验证需求

内置Filed Types

AutoField 主键,不指定主键django将自动添加一个名为id的主键。

BigAutoField 主键 biginteger

BinaryField 二进制类型
    默认状况下,BinaryField的editable属性为False,不容许包含在ModelForm中
    慎用,此字段不能代替真正的文件处理

BooleanField 布尔类型
    widget默认为CheckboxInput,若是null=True则为NullBolleanSelect
    若是Field.default没有指定,BooleanField默认值为None

CharField string类型
    若是数据量很大,使用TextFiled
    widget默认为TextInput

DateField datetime.date类型
    auto_now属性,设置为True时执行model.save自动更新此字段为当前时间,且修改此字段值将无效
    auto_now_add属性,设置为True时执行model.add自动添加此字段为当前时间,且修改此字段值将无效
    若是你只想修改这个字段,使用defalut=tdate.today,它将datetime.date.today()赋值给此字段,且支持修改。对于DateTimeField类型,使用default=timezone.noe,它将django.utils.timezone.now()赋值给此字段。
    auto_now_add, auto_now, default是独有的,不能混合使用
    auto_now or auto_now_add to True将致使 editable=False and blank=True 
    auto_now和auto_now_add选项在建立或更新时老是使用默认时区中的日期

DateTimeField datetime.datetime类型
    与DateField相似

DecimalField Decimal类型
    max_digits属性 最大位数
    decimal_places属性 小数位数
    最大位数-小数位数=最大整数位数

DurationField 时间间隔字段
    在大多数状况下,使用DurationField算法是可行的。然而,在除PostgreSQL以外的全部数据库上,将DurationField的值与DateTimeField实例上的算术值进行比较将没法正常工做

EmailField email类型

FileField 文件上传类型
    upload_to属性 设置文件上传的路径
        upload = models.FileField(upload_to='uploads/')
        upload = models.FileField(upload_to='uploads/%Y/%m/%d/')
    使用 FileField,须要对settings.py作以下配置
        # 与用户上传相关的配置
        MEDIA_URL="/media/"  # 访问路径
        MEDIA_ROOT=os.path.join(BASE_DIR,"media")  # 保存路径

    upload_to也能够是一个方法
        def user_directory_path(instance, filename):
            # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
            return 'user_{0}/{1}'.format(instance.user.id, filename)
        
        class MyModel(models.Model):
            upload = models.FileField(upload_to=user_directory_path)

    当访问FileField时,会获得一个FieldFile实例,做为访问底层文件的代理。

FilePathField 文件路径类型
    当你只想保存已存在的文件路径而不是获取用户上传的文件时使用此字段,不使用FileField

    class FilePathField(path=None, match=None, recursive=False, max_length=100, **options)
    一个CharField,其选择仅限于文件系统上某个目录中的文件名。有三个特殊的参数,第一个是必须的

    path:文件路径,最好配置在settings.py中
    match:文件名正则匹配表达式
    recursive:指定是否应包括路径的全部子目录
    allow_files:指定是否应包括指定位置中的文件 必须是True
    allow_folders:指定是否包含指定位置的文件夹 必须是True

FloatField 浮点类型
    将被解析成python Float类型

ImageField 图片类型
    继承了FileField类,将验证是否为图片
    height_field属性:文件save时将被保存成此字段高
    width_field属性:文件save时将被保存成此字段宽

IntegerField 整数类型
    保存int类型

GenericIPAddressField IP类型
    IPv4 or IPv6地址,默认widget是TextInput
    protocol属性:value in('both'(default) 'IPv4' 'IPv6')
    unpack_ipv4属性:解包IPv4映射地址,好比::ffff:192.0.2.1。若是启用此选项,该地址将解压缩到192.0.2.1。默认是禁用的。只能在协议设置为'both'时使用。

NullBooleanField 布尔类型
    与 BooleanField with null=True效果同样

PositiveIntegerField 正整数类型
    与 IntegerField相似,只能保存正整数

PositiveSmallIntegerField 正整数类型
    与 PositiveIntegerField相似,范围:0 to 32767

SlugField 限定string类型
    slug是对某物的缩写,仅包含字母、数字、下划线或连字符。它们一般用于url中。
    allow_unicode:设置为True时,除了ASCII还可使用unicode字符,默认为False

SmallIntegerField 整数类型
    与 IntegerField相似,范围:-32768 to 32767

TextField 文本类型
    large text filed

TimeField 时间类型
    datetime.time

URLField
    A CharField for a URL, validated by URLValidator
    The default form widget for this field is a TextInput.

UUIDField UUID类型

    import uuid
    from django.db import models
    
    class MyUUIDModel(models.Model):
        id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
        # other fields

Relationship fields
    Django还定义了一组表示关系的字段

ForeignKey 外键类型
    在多对一关系使用它

    from django.db import models
    
    class Car(models.Model):
        manufacturer = models.ForeignKey(
            'Manufacturer',
            on_delete=models.CASCADE,
        )
        # ...
    
    class Manufacturer(models.Model):
        # ...
        pass

    #ForeignKey与抽象类
    from django.db import models
    
    class AbstractCar(models.Model):
        manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
    
        class Meta:
            abstract = True

    from django.db import models
    from products.models import AbstractCar
    
    class Manufacturer(models.Model):
        pass
    
    class Car(AbstractCar):
        pass

    on_delete属性:指向的表数据删除时若是操做此字段
    limit_choices_to属性:限制指向表数据的字段值
        staff_member = models.ForeignKey(
            User,
            on_delete=models.CASCADE,
            limit_choices_to={'is_staff': True},  # 只有User表中的is_staff属性为True的才能够赋值给此字段
        )

        # limit_choices_to能够指定给一个函数
        def limit_pub_date_choices():
            return {'pub_date__lte': datetime.date.utcnow()}
        
        limit_choices_to = limit_pub_date_choices

    related_name属性:从相关对象返回到此对象的关系使用的名称。请参阅相关对象文档。注意,在定义抽象模型上的关系时,必须设置此值;当你这样作的时候,一些特殊的语法是可用的。
                     若是您但愿Django不要建立反向关系,能够将related_name设置为'+'或以'+'结束它。默认为 表名_set

    related_query_name属性:用于目标模型中反向筛选器名称的名称。
        # Declare the ForeignKey with related_query_name
        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)
        
        # That's now the name of the reverse filter
        article_obj = Article.objects.filter(tag__name="important")
        article_obj.tags.all()

    to属性:关系所在的对象

    to_field属性:关系所在的相关对象上的字段。默认状况下,Django使用相关对象的主键。若是引用不一样的字段,则该字段必须具备唯一=True。
    
    db_constraint属性:控制是否应该在数据库中为该外键建立约束。默认为真,这几乎确定是你想要的;将此设置为False可能对数据完整性很是不利。

    swappable属性:若是这个ForeignKey指向一个可切换的模型,则控制迁移框架的反应。若是它是True(默认值),那么若是ForeignKey指向的模型与设置的当前值匹配。AUTH_USER_MODEL(或另外一个可切换模型设置)关系将使用对该设置的引用而不是直接对模型的引用存储在迁移中。
    若是您确信您的模型应该始终指向被签入的模型——例如,若是它是专门为您的自定义用户模型设计的配置文件模型,那么您只但愿将其重写为False。
    将它设置为False并不意味着你能够引用一个可切换模型即便是换出——假只是意味着迁移用此ForeignKey老是参考的模型指定(这将会失败若是用户试图运行一个用户模型你不支持,例如)。
    若是有疑问,让它默认为True


ManyToManyField
    多对多关系

    limit_choices_to在ManyToManyField上使用使用through参数指定的自定义中间表时没有任何效果
    
    through属性:Django将自动生成一个表来管理多对多关系。可是,若是要手动指定中间表,可使用through选项指定Django模型,该模型表示要使用的中间表。
    through_fields属性:指定through的表后,须要声明表中关联的字段
        tags = models.ManyToManyField(
            to="Tag",
            through='Article2Tag',
            through_fields=('article', 'tag'),
        )

        class Article2Tag(models.Model):
            nid = models.AutoField(primary_key=True)
            article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid', on_delete=models.CASCADE)
            tag = models.ForeignKey(verbose_name='标签', to="Tag", to_field='nid', on_delete=models.CASCADE)
    db_table属性:django自动生成关系表的名称,不指定此值将有一个默认值

OneToOneField
    一对一关系

    related_name属性:若是不为OneToOneField指定related_name参数,Django将使用当前模型的小写名称做为默认值。
相关文章
相关标签/搜索