Django的Model

 整理记录一下Django的Model相关内容,工作中实际用到的点其实不是非常多,但是可以对于Model的一些特性做一些记录,也许长久会发现一些比较好的方式来做同样的事情。

一、Basic

1、每个model   django.db.models.Model  的子类

来自 <https://docs.djangoproject.com/en/1.11/topics/db/models/>

2、每个model 的属性代表一个数据库字段

3Django 提供一个自动生成的数据库访问APIORM),

Making queries

 

来自 <https://docs.djangoproject.com/en/1.11/topics/db/models/>

 

二、创建实例

1

2

3

4

5

from django.db import models

 

class Person(models.Model):

    first_name = models.CharField(max_length=30)

    last_name = models.CharField(max_length=30)

 

来自 <http://tool.oschina.net/highlight>

 

上述代码实现定义了一个Person,包含first_namelast_name

 

相对应的数据库表的创建如下:

1

2

3

4

5

CREATE TABLE myapp_person (

    "id" serial NOT NULL PRIMARY KEY,

    "first_name" varchar(30) NOT NULL,

    "last_name" varchar(30) NOT NULL

);

 

来自 <http://tool.oschina.net/highlight>

 

其中:创建的表名带了app的名字,且全为小写。 默认带了一个主键id

 

三、使用

1、需要在setting文件中的 INSTALLED_APPS 下新增 app的名称

INSTALLED APPS ( ' django. contrib . auth ' , ' django. contrib . contenttypes ' ' django. contrib . sessions ' ' django. contrib . sites ' , ' django. contrib . messages ' ' django. contrib . staticfiles ' , ' accounts ' , ' audit', ' dashboard' , ' list ' , ' materials ' ,

 

当新增了app之后,需要执行:

    manage.py migrate

也可以先执行

   manage.py makemigrations  进行数据迁移

 

数据库字段都是通过类属性来确定,字段名称不要与models API冲突,比如cleansave

 

四、字段选项

 

 choices

1

2

3

4

5

6

7

8

9

10

from django.db import models

 

class Person(models.Model):

    SHIRT_SIZES = (

        ('S', 'Small'),

        ('M', 'Medium'),

        ('L', 'Large'),

    )

    name = models.CharField(max_length=60)

    shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)

 

来自 <http://tool.oschina.net/highlight>

 

 

1

2

3

4

5

6

>>> p = Person(name="Fred Flintstone", shirt_size="L")

>>> p.save()

>>> p.shirt_size

'L'

>>> p.get_shirt_size_display()

'Large'

 

来自 <http://tool.oschina.net/highlight>

 

数据库存储第一列的数据,想要获取字段展示的值,使用get_FOO_display() ,这里FOO指的就是choice数据的名称

 

 primary_key

如果primary_ket=True 这个字段就是主键。如果未指定,django会自动生成一个IntegerField作为主键

自动生成的主键字段(自增主键)django默认给每个models使用下面语句分配主键

1

id = models.AutoField(primary_key=True)

 

来自 <http://tool.oschina.net/highlight>

 

 

字段自述名 (verbose name)

除了ForeignKeyManyToManyFieldOneToOneField,以外的所有字段类型都使用一个参数作为字段自述名的位置参数。如果未命名,则默认为字段的属性名(变量名)将下划线换成空格显示。

 positional argument

 

1

first_name = models.CharField("person's first name", max_length=30)

 

来自 <http://tool.oschina.net/highlight>

 

verbose name person's first name

 

1

first_name = models.CharField(max_length=30)

 

来自 <http://tool.oschina.net/highlight>

verbose name first name

 

ForeignKeyManyToManyFieldOneToOneField 需要第一个参数必须为模型类(model class),所以使用verbose_name关键字参数指定。

 

 

五、跨文件模型

使用其他appmodels,只需要在当前models文件顶部引用其他models

 

Meta 选项:

一般用于 任何不是字段的数据,比如排序(ordering 数据库表名 ( db_table )。。 可选项,非必须项。排序会增加数据库的开销

 

1

2

3

4

5

6

7

8

from django.db import models

 

class Ox(models.Model):

    horn_length = models.IntegerField()

 

    class Meta:

        ordering = ["horn_length"]

        verbose_name_plural = "oxen"

 

来自 <http://tool.oschina.net/highlight>

 

 

Model 属性

1、最重要的一个属性就是Manager,是Django模型进行数据查询的接口,用于从数据库获取实例。如果没有定义Manager,则默认名称为objects Manager只能通过模型类访问而不能通过模型实例。

 

定义Manager

1

2

3

4

5

from django.db import models

 

class Person(models.Model):

    #...

    people = models.Manager()

 

来自 <http://tool.oschina.net/highlight>

 

如果这样定义之后,使用Person.objects 会出现AtrributeError 异常。但是使用Persoon.people.all()就能获取到Person对象的列表。

未定义则使用默认的objectsPerson.objects.all()

 

六、模型方法

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=50)

    last_name = models.CharField(max_length=50)

 

    @property

    def full_name(self):

        "Returns the person's full name."

        return '%s %s' % (self.first_name, self.last_name)

 

来自 <http://tool.oschina.net/highlight>

 

 full_name 函数就是模型Person的方法,和一般的Python的类方法没什么特殊区别

 

重写预定义的模型方法:

一些封装好的数据库操作,如果想自定义这些方法,比如save() 或者 delete()

1

2

3

4

5

6

7

8

9

10

from django.db import models

 

class Blog(models.Model):

    name = models.CharField(max_length=100)

    tagline = models.TextField()

 

    def save(self, *args, **kwargs):

        do_something()

        super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.

        do_something_else()

 

来自 <http://tool.oschina.net/highlight>

 

确保调用super(Blog, self).save(*args, **kwargs) 来完成数据被保存到数据库。如果不调用默认的行为不会发生并且数据库不会被改变

 

七、模型继承

Django的基础类型必须是  django.db.models.Model 的子类

Django中有三种继承类型:

1、抽象基类(abstract baseclasses 如果不想在多个子类中重复的保存信息,可以存在父类中;这种类型不会封闭的使用。

2、多表继承(multi-tableinheritance)如果想子类化一个已经存在的模型,并且向每个模型拥有自己的数据表

3、代理模型(proxy models)如果想修改模型的Python层次的行为,并且在任何情况下都不改变模型的字段

 

抽象基类:
定义抽象基类,设置
abstract=True

1

2

3

4

5

6

7

8

9

10

11

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)

 

来自 <http://tool.oschina.net/highlight>

Student模型将会有三个字段:name, age, home_group

抽象基类不能像正常的Django模型那样使用:不会生成数据表,不会有manager,不能被实例化以及直接保存

元类继承:

当抽象基类被创建,Django会把在基类中声明的任何Meta内部类作为一个属性。如果子类没有声明自己的Meta类,将会继承父类的Meta类。如果子类想扩展父类的Meta类,可以在子类中声明创建:

1

2

3

4

5

6

7

8

9

10

11

12

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'

 

来自 <http://tool.oschina.net/highlight>

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值