Django 模型

Django也遵循了MVC的分层原则,不过在做法上略有不同。
    首先模型部分保持不变:Django的模型增只负责把数据传入传出数据库。然而Django里的视图却并不是显示数据的最后一步----Django的视图其实更接近MVC里传统意义上的控制器。他们是用来将模型层和表示层(有HTML和Django的模板语言组成)链接在一起的python函数。
按Django开发团队的话老说就是: 我们理解的MVC里,视图的作用是描述将要显示给用户的数据。这不仅仅是数据看上去的外观,含包括如何表示数据。视图描述的是你能看那些数据,而不是怎么看到它。
    换一种说法,Django把表示层一分为二,视图方法定义了要显示模型里的什么数据,而模板则定义了最终信息的显示方式。
而框架自己则担当了控制器的角色--它提供了决定什么视图和什么模板一起响应给定请求的机制。

一、模型的定义

1、基础

    |-每个模型都是django.db.models.Model 的一个Python 子类。
    |-模型的每个属性都表示数据库中的一个字段。
    |-Django 提供一套自动生成的用于数据库访问的API;
    |-模型表名为 myapp_modelname

2、字段

django常见Field Types:
    1、AutoField
    如果没有指明主键,就会产生一个自增的主键。
    2、BigIntegerField
    64位的整型数值,从 -2^63 (-9223372036854775808) 到 2^63-1(9223372036854775807)。
    3、BinaryField
    存储原始二进制数据,仅支持字节分配。功能有限。
    4、BooleanField
    布尔型和NullBooleanField有区别,true/false,本类型不允许出现null。
    5、CharField
    字符串,一般都在创建时写入max_length参数。
    6、CommaSeparatedIntegerField
    逗号分隔的整数,考虑到数据库的移植性,max_length参数应该必选。
    原文解释:A field of integers separated by commas. As in CharField, the max_length argument is required and the note about database portability mentioned there should be heeded.
    7、DateField
    时间,对应Python的datetime.date,额外的参数:DateField.auto_now表示是否每次修改时改变时间,DateField.auto_now_add 表示是否创建时表示时间,一般来说数据库重要的表都要有这样的字段记录创建字段时间个最后一次改变的时间。关于时间的话,建议timestamp,当然 python的话还是DateTime吧。
    8、DateTimeField
    对应Python的datetime.datetime,参照参数(7)。
    9、DecimalField
    固定精度的十进制数,一般用来存金额相关的数据。对应python的Decimal,额外的参数包括DecimalField.max_digits和DecimalField.decimal_places ,这个还是要参照一下mysql的Decimal类型,http://database.51cto.com/art/201005/201651.htm
    例如:price = models.DecimalField(max_digits=8,decimal_places=2)
    10、EmailField
    字符串,会检查是否是合法的email地址
    11、FileField
    class FileField([upload_to=None, max_length=100, **options])
    存文件的,参数upload_to在1.7之前的一些老版本中必选的
    12、FloatField
    浮点数,必填参数:max_digits,数字长度;decimal_places,有效位数。
    13、ImageField
    class ImageField([upload_to=None, height_field=None, width_field=None, max_length=100, **options])
    图片文件类型,继承了FileField的所有属性和方法。参数除upload_to外,还有height_field,width_field等属性。
    14、IntegerField
    [-2147483648,2147483647 ]的取值范围对Django所支持的数据库都是安全的。
    15、IPAddressField
    点分十进制表示的IP地址,如10.0.0.1
    16、GenericIPAddressField
    ip v4和ip v6地址表示,ipv6遵循RFC 4291section 2.2,
    17、NullBooleanField
    可以包含空值的布尔类型,相当于设置了null=True的BooleanField。
    18、PositiveIntegerField
    正整数或0类型,取值范围为[0 ,2147483647]
    19、PositiveSmallIntegerField
    正短整数或0类型,类似于PositiveIntegerField,取值范围依赖于数据库特性,[0 ,32767]的取值范围对Django所支持的数据库都是安全的。
    20、SlugField
    只能包含字母,数字,下划线和连字符的字符串,通常被用于URLs表示。可选参数max_length=50,prepopulate_from用于指示在admin表单中的可选值。db_index,默认为True。
    21、SmallIntegerField
    小整数字段,类似于IntegerField,取值范围依赖于数据库特性,[-32768 ,32767]的取值范围对Django所支持的数据库都是安全的。
    22、TextField
    文本类型
    23、TimeField
    时间,对应Python的datetime.time
    24、URLField
    存储URL的字符串,默认长度200;verify_exists(True),检查URL可用性。
    25、FilePathField
    class FilePathField(path=None[, match=None, recursive=False, max_length=100, **options])
    类似于CharField,但是取值被限制为指定路径内的文件名,path参数是必选的。
    详见官方文档:
    https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types
    
    常用字段属性
    null
    如果设置为 True , Django 存放一个 NULL 到数据库字段。默认为 False。
    blank
    如果设置为 True , 此 field 允许为 blank (空白),默认为 False。
    要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。
    choices
    一个2元元组的元组或者列表,如果执行 choices , Django 的 admin 就会使用 选择框而不是标准的 text 框填写这个 field。
    default
    field 的默认值,可以使用可调用对象(a callable object),如果使用可调用 对象,那么每次创建此 model 的新对象时调用可调用对象。常见如 datatime 。
    help_text
    help_text 的值可以在 admin form 里显示,不过即使不使用 admin ,也可以当 做描述文档使用。
    primary_key
    如果为 True , 这个 field 就是此 model 的 primary key 。
    unique
    如果为 True, 此 field 在这个 table 里必须唯一。
    verbose_name
    ForeignKey、ManyToManyField 和 OneToOneField 使用此来定义“自述名”。
   


3、关系

    多对一 : ForeignKey
    多对多 :ManyToManyField 可以自定义中介模型,源模型的ManyToManyField 字段将使用through 参数指向中介模型
    一对一 :OneToOneField

4、模型继承

|-抽象基类:通常,你只想使用父类来持有一些信息,你不想在每个子模型中都敲一遍。这个类永远不会单独使用,所以你使用抽象基类。无法生成数据表单或者管理器,并且不能实例化或者储存。
    |-多表继承:如果你继承一个已经存在的模型且想让每个模型具有它自己的数据库表,那么应该使用多表继承。Django 会自动创建一个 OneToOneField字段将子类链接至非抽象的父 model 。如果你想指定链接父类的属性名称,你可以创建你自己的 OneToOneField字段并设置 parent_link=True ,从而使用该字段链接父类。
    |-代理模型:最后,如果你只是想改变模块Python 级别的行为,而不用修改模型的字段,你可以使用代理模型。
    |-多重继承:如果多个父类含有 Meta类,只有第一个会被使用,剩下的会忽略掉(Django 1.7之前,继承多个含有id主键字段的模型不会抛出异常,但是会导致数据丢失。)。
    抽象基类:

1
2
3
4
5
6
7
8
    from django.db import models
    class CommonInfo(models.Model):
        name = models.CharField(max_length=100)
        age = models.PositiveIntegerField()
        class Meta:
            abstract = True
    class Student(CommonInfo):
        home_group = models.CharField(max_length=5)

        
    元继承(继承基类的Meta):

1
2
3
4
5
6
7
8
9
10
    from django.db import models
    class CommonInfo(models.Model):
        # ...
        class Meta:
            abstract = True
            ordering = ['name']
    class Student(CommonInfo):
        # ...
        class Meta(CommonInfo.Meta):
            db_table = 'student_info'

            
    多表继承:
 

1
2
3
4
5
6
7
   from django.db import models
    class Place(models.Model):
        name = models.CharField(max_length=50)
        address = models.CharField(max_length=80)
    class Restaurant(Place):
        serves_hot_dogs = models.BooleanField(default=False)
        serves_pizza = models.BooleanField(default=False)

        
    代理继承:

1
2
3
4
5
6
7
8
9
10
    from django.db import models
    class Person(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)
    class MyPerson(Person):
        class Meta:
            proxy = True
        def do_something(self):
            # ...
            pass

 5、Meta 选项介绍

    abstract
    如果 abstract = True, 就表示模型是 抽象基类 (abstract base class).

    app_label
    如果一个模型位于标准的位置之外(应用的models.py 或models 包),该模型必须定义它属于哪个应用:
    >=Django 1.7:定义在应用的models 模块以外的模型,不再需要app_label。

    db_table  
    该模型所用的数据表的名称

    db_tablespace
    当前模型所使用的数据库表空间 的名字。默认值是项目设置中的DEFAULT_TABLESPACE,如果它存在的话。如果后端并不支持表空间,这个选项可以忽略。

    default_related_name
    >=Django 1.8+ 这个名字会默认被用于一个关联对象到当前对象的关系。默认为 <model_name>_set。
    由于一个字段的反转名称应该是唯一的,当你给你的模型设计子类时,要格外小心。为了规避名称冲突,名称的一部分应该含有'%(app_label)s'和'%(model_name)s',它们会被应用标签的名称和模型的名称替换,二者都是小写的。详见抽象模型的关联名称。

    get_latest_by
    模型中某个可排序的字段的名称,比如DateField、DateTimeField或者IntegerField。它指定了Manager的latest()和earliest()中使用的默认字段。

    managed
    默认为True,意思是Django在migrate命令中创建合适的数据表,并且会在 flush 管理命令中移除它们。换句话说,Django会管理这些数据表的生命周期。
如果是False,Django 就不会为当前模型创建和删除数据表。如果当前模型表示一个已经存在的,通过其它方法建立的数据库视图或者数据表,这会相当有用。这是设置为managed=False时唯一的不同之处。

    order_with_respect_to
    按照给定的字段把这个对象标记为”可排序的“。这一属性通常用到关联对象上面,使它在父对象中有序。
    
    ordering
    对象默认的顺序。它是一个字符串的列表或元组。每个字符串是一个字段名,前面带有可选的“-”前缀表示倒序。前面没有“-”的字段表示正序。使用"?"来表示随机排序。

    permissions
    设置创建对象时权限表中额外的权限。增加、删除和修改权限会自动为每个模型创建。它是一个包含二元组的元组或者列表,格式为 (permission_code, human_readable_permission_name)。

    default_permissions
    >=Django 1.7.默认为('add', 'change', 'delete')。你可以自定义这个列表,比如,如果你的应用不需要默认权限中的任何一项,可以把它设置成空列表。在模型被migrate命令创建之前,这个属性必须被指定,以防一些遗漏的属性被创建。

    proxy
    如果proxy = True, 作为该模型子类的另一个模型会被视为代理模型。

    select_on_save
    默认为False。该选项决定了Django是否采用1.6之前的 django.db.models.Model.save()算法。旧的算法使用SELECT来判断是否存在需要更新的行。而新式的算法直接尝试使用 UPDATE。在一些小概率的情况中,一个已存在的行的UPDATE操作并不对Django可见。比如PostgreSQL的ON UPDATE触发器会返回NULL。这种情况下,新式的算法会在最后执行 INSERT 操作,即使这一行已经在数据库中存在。

    unique_together
    用来设置的不重复的字段组合。它是一个元组的元组,组合起来的时候必须是唯一的。它在Django后台中被使用,在数据库层上约束数据(比如,在  CREATE TABLE  语句中包含  UNIQUE语句)。

    index_together
    用来设置带有索引的字段组合.index_together = [["pub_date", "deadline"],] 列表中的字段将会建立索引(例如,会在CREATE INDEX语句中被使用)。
    >= Django 1.7.为了方便起见,处理单一字段的集合时,index_together可以是一个一维的列表。

    verbose_name
    对象的一个易于理解的名称。如果此项没有设置,Django会把类名拆分开来作为自述名,比如CamelCase 会变成camel case,

    verbose_name_plural
    该对象复数形式的名称。如果此项没有设置,Django 会使用 verbose_name + "s"。

原文地址:https://www.cnblogs.com/stevenzeng/p/5085647.html