Django 学习手记 二 建立模型层

这篇文章记录了如何创建 Django 项目的一个子应用并编写 models.py 。如有错误,请不吝赐教。

Django 框架同样遵循 MVC 开发模式。在 Django 中,我们定义 Model 数据模型并自动同步生成数据库和后台,由 Template 和 Views 处理界面并转交 URLconf 控制器。

因为 MVC 中 C (Controller) 的部分主要交给框架进行,我们也将 Django 称为 MTV (Model, Template, Views) 模式。 参见

一个 Django 项目有两种层级,称为 project 项目 和 app 应用。一般来说,一个 project 就是一个完整的站点,比如一个大型论坛或者门户站点。而一个 app 就是一个有完整功能、可复用的应用,比如一个私信组件,一个投票组件或者一个讨论版。

一个 project 即使没有 app 也能独立运行,但是一个独立的 app 可以在不同的 project 中复用。另外,如果你要使用 Django 的模型功能即数据库层,模型必须存放在 app 中。

创建应用并建立模型

执行 ./manage.py startapp polls 命令,来创建一个名为 polls 的 app 。同样, Django 会自动在项目根目录下创建一个名为 polls 的目录和一系列文件。我们会以 Django 官方教程为例,先编写一个投票应用。

在这个应用中,我们需要 Quesntion 问题和 Choice 选项两个类,并且添加一系列的属性。

首先,我们编辑 polls/models.py ,这个文件就是你的模型:

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    authors = models.ManyToManyField(Author)

        # class Meta:
        # date = ["pub_date"]
        # text_filed_name = “question”

class Choice(models.Model):
    question = models.ForeignKey(Question)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

代码很容易理解。为 question_text 这样的属性名提供一个易读的名字会方便接下来的开发。

对于一个类,提供一个名为 Meta 的内嵌类,可以存放一些「不是 Field」的 Field ,比如排序信息,数据库名。详见

应用更改

编辑完成后,我们修改 project 根目录的 settings.py ,找到 INSTALLED_APPS ,在已安装应用列表的底部加上我们自己的新 app 'polls' 。这里也列出了其他的自带 app ,如果用不着,可以注释掉。

运行 ./manage.py makemigrations polls 以生成更改。这个命令同时会生成类似 polls/migrations/0001_initial.py 的脚本文件,它们是人类可读的,但是一般你不需要太过在意。使用 ./manage.py sqlmigrate polls 0001 命令可以查看生成的数据库命令。

最后使用 ./manage.py migrate 迁移命令,应用更改到数据库。

下篇文章将会介绍如何使用 ./manage.py shell 测试当前的数据模型、以及关于元素间互相绑定和关联的详情。元素绑定详见

Field 类型参考

下面是一些常用的 Field 类型和部分特有的参数。

  • ForeignKey(Class_Name, limit_choices_to={‘key_name’: value}, on_delete=models.SET_NULL)
    • 绑定一个其他类的元素(类名、可以是 ‘self’, 对于目标的属性的限制条件,关联目标被删除时的操作)
    • 一般会生成一个下拉列表
  • ManyToManyField # 多对多关联,用法同上
  • OneToOneField # 单对单关联,用法同上
  • CharField(max_length = 100) # 字符
  • TextField(max_length = 100) # 字符
  • SlugField # 为 CMS 预留的别名栏,用法同上
  • DateField(auto_now/auto_now_add)
    • 日期 (自动设为最后编辑日期/自动设为首次创建日期)
  • TimeField # 时间
  • DateTimeField # 日期和时间,参数同上
  • IntegerField # 实数
  • BigIntegerField # 大实数
  • FloatField # 浮点数
  • BooleanField # True or False 单选
  • EmailField # 邮件
  • IPAddressField # IP 地址
  • GenericIPAddressField(protocol=ipv4, unpack_ipv4=False)
    • 自动获得 IP 地址(协议限制,解包去掉 ::ffff: 前缀)
  • URLField # URL 地址
  • FileField(upload_to = ‘photos/%Y/%m/%d’ )
  • ImageField
    • 图片,参数同上,可以通过 height_field 和 width_field 熟悉拿到宽高
  • FilePathField(path="/home/images", match=“*.png”, recursive=True, allow_files = True, allow_folders = False)
    • 文件路径(起始路径,正则匹配,包含子目录,允许选择文件,允许选择目录)

Field 参数参考

以下是一些其他常用的通用参数。

  • blank = true # 该属性可为空
  • null = Ture # 该属性可为 null
  • choices = a_list_or_a_tuple # 该属性从一个列表中选择,值的具体写法见列表结束
  • default = 'A default value' # 设置默认值
  • validators = [validate_even] # 设置数据有效性验证器 详见

使用如下形式的,最终的每个元素是 (‘option value’, ‘option name’) 形式的元组的多层嵌套元组,可以定义一个任意层级的可选列表。最终将会在 HTML 中生成多个 select 下拉列表的形式。第一项是 None 的元组会被作为默认选项。详见

MEDIA_CHOICES = (
    ( None, 'Unknown' ),
    ( 'Audio', ( ('vinyl', 'Vinyl'), ('cd', 'CD'), ) ),
    ( 'Video', ( ('vhs', 'VHS Tape'), ('dvd', 'DVD'), ) ),
)

30 thoughts on “Django 学习手记 二 建立模型层

      • 我完全不打算放弃这个项目,不过具体是什么时候重启开发,就不太好说了 …… 最坏的情况也许要等到高中毕业。但愿不会。

  1. 要不是点击发表评论浏览器有提醒,不然根本没发现这里居然有个评论框==
    给子评论加缩进吧,看着怪难受

    • 还新主题,你做出来过几个 ((
      这个是用了个 jQuery 库,你翻翻我引用的 JS 文件就有了,使用方法也就两行。

  2. Pingback: Django 与 Django Rest Framework —— 配置,部署与使用 | 沙子小房間

发表评论

邮箱地址不会被公开。 必填项已用*标注