Django模型

模型是你的数据的唯一的、权威的信息源。它包含你所储存数据的必要字段和行为。通常,每个模型对应数据库中唯一的一张表

1.基础

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

2.简单例子 

  定义了一个UserMessage模型(相当于数据库中的一张表),它有5个属性(相当于数据库中的字段)。每个字段都被指定成一个类属性,每个属性映射到一个数据库的列。

class UserMessage(models.Model):
    # 自动生成一个ID主键
    object_id = models.CharField(max_length=20, primary_key=True, default='', verbose_name=u"主键")
    name = models.CharField(max_length=20,verbose_name=u"用户名")
    email = models.EmailField(verbose_name=u"邮箱")
    address = models.CharField(max_length=100,verbose_name=u"邮箱")
    message = models.CharField(max_length=500,verbose_name="留言")

  上述创建过程,相当于数据创建表的过程,如下:

CREATE TABLE UserMessage (
     object_id INT(20)  PRIMARY KEY,
     name varchar(20) NOT NULL,
     email varchar(30) NOT NULL
     address varchar(100) NOT NULL
     email varchar(50) NOT NULL
);

  注:如果没有定义主键,Django会默认生成一个id字段的作为主键。

3.使用模型

  定义好模型之后,接下来你需要告诉Django 使用这些模型。你要做的就是修改配置文件中的INSTALLED_APPS 设置,在其中添加models.py所在应用的名称。

  具体路径:settings--->INSTALLED_APPS------>'message'

  上述操作完成后,先执行manage.py makemigrations给应用生成迁移脚本,然后执行manage.py migrate。

  makemigrations 命令负责保存你的模型变化到一个迁移文件 - 和 commits很类似 - 同时 migrate负责将改变提交到数据库。

4.字段

  对于一个模型来说,最重要的和不可或缺的是列出该模型在数据库中定义的字段。字段由models类属性指定。要注意选择的字段名称不要和模型 API 冲突,比如cleansave 或者delete

  例如:

from django.db import models

class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)

class Album(models.Model):
    artist = models.ForeignKey(Musician)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()

5.字段类型

  模型中的每个字段都是 Field 子类的某个实例。Django 自带数十种内置的字段类型;

6.字段的自述名

  除ForeignKeyManyToManyField 和 OneToOneField 之外,每个字段类型都接受一个可选的位置参数(在第一的位置) —— 字段的自述名。如果没有给定自述名,Django 将根据字段的属性名称自动创建自述名 —— 将属性名称的下划线替换成空格。

  在这个例子中,自述名是 "person's first name":

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

  在这个例子中,自述名是  "first name"

first_name = models.CharField(max_length=30)

  ForeignKeyManyToManyField 和 OneToOneField 都要求第一个参数是一个模型类,所以要使用 verbose_name 关键字参数才能指定自述名

poll = models.ForeignKey(Poll, verbose_name="the related poll")
sites = models.ManyToManyField(Site, verbose_name="list of sites")
place = models.OneToOneField(Place, verbose_name="related place")

7.关系

  Django 提供了三种最常见的数据库关系:多对一(many-to-one),多对多(many-to-many),一对一(one-to-one)。

  • 多对一关系

  Django 使用 django.db.models.ForeignKey 定义多对一关系。和使用其它字段类型一样:在模型当中把它做为一个类属性包含进来

  ForeignKey 需要一个位置参数:与该模型关联的类。

  比如,一辆汽车(Car)有一个制造商(Manufacturer) —— 但是一个制造商(Manufacturer) 生产很多汽车(Car),每一辆汽车(Car) 只能有一个制造商(Manufacturer) —— 使用下面的定义:

from django.db import models

class Manufacturer(models.Model):
    # ...
    pass

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer) # 一对多的关系,外键放在多的一方
    # ...                                  可以设置第二个参数verbose_name="related place"

  多对一实例:

from django.db import models

class Reporter(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField()

    def __str__(self):              # __unicode__ on Python 2
        return "%s %s" % (self.first_name, self.last_name)

class Article(models.Model):
    headline = models.CharField(max_length=100)
    pub_date = models.DateField()
    reporter = models.ForeignKey(Reporter)

    def __str__(self):              # __unicode__ on Python 2
        return self.headline

    class Meta:
        ordering = ('headline',)
View Code
  • 多对多关系 

  ManyToManyField 用来定义多对多关系,用法和其他Field 字段类型一样:在模型中做为一个类属性包含进来。

  ManyToManyField 需要一个位置参数:和该模型关联的类。

  例如,一个披萨可以有多种馅料 ,一种馅料 也可以位于多个披萨上。 如下展示:

from django.db import models

class Topping(models.Model):
    # ...
    pass

class Pizza(models.Model):
    # ...
    toppings = models.ManyToManyField(Topping)

  建议你以被关联模型名称的复数形式做为ManyToManyField 的名字(例如上例中的toppings)。

  在哪个模型中设置 ManyToManyField 并不重要,在两个模型中任选一个即可 —— 不要两个模型都设置。

  应用实例:

from django.db import models

class Publication(models.Model):
    title = models.CharField(max_length=30)

    def __str__(self):              # __unicode__ on Python 2
        return self.title

    class Meta:
        ordering = ('title',)

class Article(models.Model):
    headline = models.CharField(max_length=100)
    publications = models.ManyToManyField(Publication)

    def __str__(self):              # __unicode__ on Python 2
        return self.headline

    class Meta:
        ordering = ('headline',)
View Code

  有些情况下,Django 允许你指定一个中介模型来定义多对多关系。 你可以将其他字段放在中介模型里面。源模型的ManyToManyField 字段将使用through 参数指向中介模型。对于上面的音乐小组的例子,代码如下:

from django.db import models

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

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

  在设置中介模型时,要显式地指定外键并关联到多对多关系涉及的模型。这个显式声明定义两个模型之间是如何关联的。

  中介模型有一些限制:

    • 中介模型必须有且只有一个外键到源模型(上面例子中的Group),或者你必须使用ManyToManyField.through_fields 显式指定Django 应该在关系中使用的外键。如果你的模型中存在不止一个外键,并且through_fields没有指定,将会触发一个无效的错误。 对目标模型的外键有相同的限制(上面例子中的 Person)。
    • 对于通过中介模型与自己进行多对多关联的模型,允许存在到同一个模型的两个外键,但它们将被当做多对多关联中一个关系的两边。如果有超过两个外键,同样你必须像上面一样指定through_fields,否则将引发一个验证错误。
    • 使用中介模型定义与自身的多对多关系时,你必须设置 symmetrical=False.
  •  一对一关系

  OneToOneField用来定义一对一关系。 用法和其他字段类型一样:在模型里面做为类属性包含进来。

  当某个对象想扩展自另一个对象时,最常用的方式就是在这个对象的主键上添加一对一关系。

  OneToOneField要一个位置参数:与模型关联的类。

8.字段名限制

  Django 对字段的命名只有两个限制:

    字段的名称不能是Python 保留的关键字,因为这将导致一个Python 语法错误。

class Example(models.Model):
    pass = models.IntegerField() # 'pass' is a reserved word!

    由于Django 查询语法的工作方式,字段名称中连续的下划线不能超过一个。

class Example(models.Model):
    foo__bar = models.IntegerField() # 'foo__bar' has two underscores!

9.Meta的使用

from django.db import models

class UserMessage(models.Model):
    # 自动生成一个ID主键
    object_id = models.CharField(max_length=20, primary_key=True, default='', verbose_name=u"主键")
    name = models.CharField(max_length=20,verbose_name=u"用户名")
    email = models.EmailField(verbose_name=u"邮箱")
    address = models.CharField(max_length=100,verbose_name=u"邮箱")
    message = models.CharField(max_length=500,verbose_name="留言")

    class Meta: # 元信息使用
        verbose_name = u"用户留言信息"
        ordering = ["name"]  # 按照名字排序
        db_table = "userinfo"

  模型元数据是“任何不是字段的数据”,比如排序选项(ordering),数据库表名(db_table)或者人类可读的单复数名称(verbose_name 和verbose_name_plural)。在模型中添加class Meta是完全可选的,所有选项都不是必须的。

  模型元

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

db_table = 'music_album'  数据表的名称,在 MySQL中使用小写字母为表命名

ordering = ['-order_date'] 每个字符串是一个字段名,前面带有可选的“-”前缀表示倒序。前面没有“-”的字段表示正序。使用"?"来表示随机排序。
    ordering = ['pub_date'] 正序排序
    ordering = ['-pub_date'] 倒序排序
    ordering = ['-pub_date', 'author'] 先按照pub_date的倒序排序,再按照 author 的正序排序
    verbose_name = "pizza" 对象的一个易于理解的名称,为单数;如果此项没有设置,Django会把类名拆分开来作为自述名,比如CamelCase 会变成camel case
    verbose_name_plural = "stories" 对象复数形式的名称;如果此项没有设置,Django 会使用 verbose_name + "s"
View Code

10.模型的方法 

  可以在模型上定义自定义的方法来给你的对象添加自定义的“底层”功能。Manager 方法用于“表范围”的事务,模型的方法应该着眼于特定的模型实例。

  这是一个非常有价值的技术,让业务逻辑位于同一个地方 —— 模型中。

  例如,下面的模型具有一些自定义的方法:

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    birth_date = models.DateField()

    def baby_boomer_status(self):
        "Returns the person's baby-boomer status."
        import datetime
        if self.birth_date < datetime.date(1945, 8, 1):
            return "Pre-boomer"
        elif self.birth_date < datetime.date(1965, 1, 1):
            return "Baby boomer"
        else:
            return "Post-boomer"

    def _get_full_name(self):
        "Returns the person's full name."
        return '%s %s' % (self.first_name, self.last_name)
    full_name = property(_get_full_name)

  

更多相关信息参考:http://python.usyiyi.cn/translate/django_182/topics/db/models.html

posted @ 2017-08-02 20:15  看雪。  阅读(256)  评论(0编辑  收藏  举报