`
剑事
  • 浏览: 62953 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Django 1.0 中文文档-----模型语法

阅读更多

编写模型

 

一个模型是单独的明确的数据源,他包括必要的字段和数据存储行为,通常一个模型对应数据库里的一个表。

 

基本上:

  • 每个模型都是django.db.models.Model的一个子类
  • 每个模型属性都描述了一个数据库的字段
  • django提供了一套自动的数据库操作API

例子

 

这个例子定义了一个Person,有first_namelast_name 两个字段

from django.db import models

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

 

Person 将会创建一个数据库表,如:

 

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

 

 

一些注意

  • 表名默认自动命名为myapp_person,当然这个也可以由我们自己自定义
  • ID字段是自动添加的主键字段,这个也可以自定义覆盖
  • 生成的SQL脚本会根据使用的数据库不通而有所不同

使用模型

 

定义好模型后,我们需要告诉DJANGO使用他,在settings.py的INSTALLED_APPS 加入

 

 

INSTALLED_APPS = (
    #...
    'mysite.myapp',
    #...
)

 

然后执行命令

 

 

 manage.py syncdb.

 

字段

 

这是模型中最重要的部分,字段是定义为属性类

 

 

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()

 

字段类型

 

每个模型里的字段都要实例化一个合适的字段类,django通过字段类确定一些信息

 

  • 数据库字段类型 
  • Django管理接口组件
  • 最小值验证

Django提供了很多字段类型

 

字段选项

 

每个字段都有一些参数,例如CharField  需要  max_length 来指定数据库VARCHAR 列的字段长度

 

null
允许为空.
blank

允许为空白

choices

          选择集合,如下

         

YEAR_IN_SCHOOL_CHOICES = (
    ('FR', 'Freshman'),
    ('SO', 'Sophomore'),
    ('JR', 'Junior'),
    ('SR', 'Senior'),
    ('GR', 'Graduate'),
)

 

 

default
默认值
help_text
在表单字段下显示的关于本字段的说明信息(管理接口) 
primary_key

主键

  unique
  唯一约束

 

自动递增主键

 

每个模型默认有 id = models.AutoField(primary_key=True)

详细字段名

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

如果是ForeignKey, ManyToManyField OneToOneField 这类字段的标签

 

sites = models.ManyToManyField(Site, verbose_name="list of sites")

 

 

关系

 

关系数据库功能在于建立表间关系,Django提供了三种字段类型建立关系,many-to-one, many-to-many 和 one-to-one

 

many-to-one(多对一) 关系

 

要定义一个多对一关系,使用ForeignKey. 使用方法和其他字段使用方式一样。

ForeignKey 需要一个定位参数,即要关联的类。

例如一个Car模型有一个Manufacturer,很多个Car出自一个Manufacturer,那么使用如下方式定义

 

 

 

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

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer)
    # ...

 

Many-to-many(多对多) 关系

 

要定义一个多对一关系,使用ManyToManyField.使用方法和其他字段使用方式一样。

ManyToManyField需要一个定位参数,即要关联的类。

 

例如,pizza包含多种配料,一种配料用于多种PIZZA,可以如下表现:

 

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

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

 

和ForeignKey一样也可以建立递归关系。

上面代码里topping建议用复数形势。

ManyToManyField也支持其他参数选项,定义描述关系。

 

额外的many-to-many字段关系

 

当你只处理简单的多对多关系时,如混合并匹配pizzas和配料,你需要一个标准的ManyToManyField 。然而,有时你可能关联两个模型之间的数据。

 

举个例子追踪一个乐队音乐家的归属,有一个人和组的多对多关系,你可以用ManyToManyField 描述,然而,有好多会员(Membership)详细资料需要采集,如加入乐队的时间。在这些情况下,Django允许你指定模型控制多对多关系,你可以为中间模型分配额外字段,使用through 参数指向一个中介,我们这个例子代码如下:

 

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

    def __unicode__(self):
        return self.name

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

    def __unicode__(self):
        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)

 

中间模型有一些约束

 

  • 中间模型必须包含一个且只有一个外键关联指定目标模型(中间模型多对多字段的模型,这里是person),否则会报错。
  • 中间模型必须包含一个且只有一个外键关联指定源模型(这里是Group模型),否者会报错。
  • 通过中间模型,自身多对多关系是例外的。在这种情况下,两个外键相同的模式是允许的,但他们将被视为两个(不同的)双方的多对多关系。
  • 当定义多对多关系时,用中间模型你必须用symmetrical=False

现在你已经建立好了多对多关系使用中间模型, 你开始创建多对多关系,建立实例

 

>>> ringo = Person.objects.create(name="Ringo Starr")
>>> paul = Person.objects.create(name="Paul McCartney")
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
...     date_joined=date(1962, 8, 16),
...     invite_reason= "Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all()
[<Person: Ringo Starr>]
>>> ringo.group_set.all()
[<Group: The Beatles>]
>>> m2 = Membership.objects.create(person=paul, group=beatles,
...     date_joined=date(1960, 8, 1),
...     invite_reason= "Wanted to form a band.")
>>> beatles.members.all()
[<Person: Ringo Starr>, <Person: Paul McCartney>]

 

和通常的多对多字段不同,你不能使用add, create, 或 assignment 创建关系

 

# 这样不行
>>> beatles.members.add(john)
# 这样也不行
>>> beatles.members.create(name="George Harrison")
# 这样不行
>>> beatles.members = [john, paul, ringo, george]

 为什么呢?你不能在Person 和 Group 之间创建关系,你需要指定所有详细资料给Membership 来建立关系,add, create 和assignment不能提供额外的信息,所以当用中间模型的多对多关系时他们不能被使用

 

remove 方法也是不能用的,clear来代替删除方法。

 

 

# Beatles have broken up
>>> beatles.members.clear()

 

一旦你确定了中间模型的多对多关系,你可以关系查询。

 

 

# Find all the groups with a member whose name starts with 'Paul'
>>> Groups.objects.filter(members__name__startswith='Paul')
[<Group: The Beatles>]

 

使用中间模型,你可以使用他的属性来查询

 

# Find all the members of the Beatles that joined after 1 Jan 1961
>>> Person.objects.filter(
...     group__name='The Beatles',
...     membership__date_joined__gt=date(1961,1,1))
[<Person: Ringo Starr]

 

一对一关系

 

要定义一个多对一关系,使用OneToOneField. 使用方法和其他字段使用方式一样。

OneToOneField 需要一个定位参数,即要关联的类。

 

举个例子,如果你要建立一个地点数据库,你需要建立漂亮标准的资料,如地址电话等,然后如果你要建立一个餐馆数据库在地区之上,你需要替换重复的字段,和地点建立一对一关系 

 

 

模型跨文件

 

模型的关联可以跨两个应用程序之间,可以在顶部输入其他模型,例如:

 

from mysite.geography.models import ZipCode

class Restaurant(models.Model):
    # ...
    zip_code = models.ForeignKey(ZipCode)

 

字段名字规则

 

django字段有两个命名规则:

 

   1.字段名字不能是python语言的预定义关键字,如‘pass’,否者会编译出错

     

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

 

   2.字段名不能包含多于一个连着的下划线,这是避免和django的查询语法规则冲突。

   

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

 

 

 

自定义字段类型

 

在新的django 1.0版本,我们可以自己定义模型的字段类型,这个可以详细参考自定义字段类型文档部分。

 

元选项

 

通过内部类的方式给你的模型提供元数据。

 

class Ox(models.Model):
    horn_length = models.IntegerField()

    class Meta:
        ordering = ["horn_length"]
        verbose_name_plural = "oxen"

 

模型元数据不是字段,像指令选项(排序),数据表名,可读的单数复数,这些参数不是必要的。

 

模型方法

 

可一个为模型添加自定义方法,让模型有逻辑功能是比较有价值的,例如下面模型有些自定的方法:

 

from django.contrib.localflavor.us.models import USStateField

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    birth_date = models.DateField()
    address = models.CharField(max_length=100)
    city = models.CharField(max_length=50)
    state = USStateField() # Yes, this is America-centric...

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

    def is_midwestern(self):
        "Returns True if this person is from the Midwest."
        return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO')

    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)

 

最后一个方法被设置成了属性,关于属性的特性说明可查看相关资料。

 

你也可以覆盖默认的一些方法

 

__unicode__()  unicode方式返回字符

get_absolute_url() 获取觉得链接

 

 

覆盖预定义的模型方法

 

有时候我们需要重新实现模型的一些方法 如save() 和 delete()

 

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def save(self, force_insert=False, force_update=False):
        do_something()
        super(Blog, self).save(force_insert, force_update) # Call the "real" save() method.
        do_something_else()

 

 

也可以这样

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def save(self, force_insert=False, force_update=False):
        if self.name == "Yoko Ono's blog":
            return # Yoko shall never have her own blog!
        else:
            super(Blog, self).save(force_insert, force_update) # Call the "real" save() method.

 

执行自定义SQL

 

当需要执行自定义SQL时,可以如下方式:

def my_custom_sql(self):
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    row = cursor.fetchone()
    return row

 

模型的继承

 

django的模型继承和python的标准类的继承是一样的,如果多个模型有同样部分,可以将共同的部分作为父类继承。

 

抽象类 

 

当你想将一些共用信息加入到一些模型里时抽象类就显得很重要了,你编写一个基本类并设置abstract=True,这样这个模型就不会被创建成表 

 

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)

 

元继承 

 

class CommonInfo(models.Model):
    ...
    class Meta:
        abstract = True
        ordering = ['name']

class Student(CommonInfo):
    ...
    class Meta(CommonInfo.Meta):
        db_table = 'student_info'

 

注意related_name 

 

如果你在用ForeignKey 或 ManyToManyField,时使用了related_name属性,你需要提供一个唯一的reverse name

 

class Base(models.Model):
    m2m = models.ManyToMany(OtherModel, related_name="%(class)s_related")

    class Meta:
        abstract = True

class ChildA(Base):
    pass

class ChildB(Base):
    pass

 

 

多表继承

 

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(Place):
    serves_hot_dogs = models.BooleanField()
    serves_pizza = models.BooleanField()

 

 

>>> Place.objects.filter(name="Bob's Cafe")
>>> Restaurant.objects.filter(name="Bob's Cafe")

>>> p = Place.objects.filter(name="Bob's Cafe")
# If Bob's Cafe is a Restaurant object, this will give the child class:
>>> p.restaurant
<Restaurant: ...>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4
0
分享到:
评论

相关推荐

    django1.0文档

    这个“django1.0文档”是官方提供的详尽指南,包含了关于 Django 1.0 的所有核心概念、功能和最佳实践,对于开发者来说是一份非常宝贵的资源。 **Django 框架基础** 1. **模型(Models)**: Django 的核心之一是它...

    Django 1.0 中文文档.doc

    《Django 1.0 中文文档》是一个详尽的指南,主要针对初学者,旨在帮助读者快速掌握Django框架的基础知识。在这个文档中,首先介绍了如何编写你的第一个Django程序,通过创建一个简单的投票应用来引导学习者逐步了解...

    PyPI 官网下载 | django-tables2-column-shifter-0.3.0.tar.gz

    然后在你的Django项目中导入并配置这个库,根据提供的文档或示例代码进行相应的设置,最后在视图(views.py)和模板(templates)中应用这些配置。 总的来说,`django-tables2-column-shifter`是Python和Django...

    Python库 | django-taggit-serializer-0.1.5.tar.gz

    django-taggit本身是一个强大的标签管理工具,它允许开发者轻松地为Django模型添加标签功能,而django-taggit-serializer则进一步简化了与JSON或其他数据格式交互的复杂性。 在安装django-taggit-serializer时,...

    Python库 | django_admin_multilang-1.0-py3-none-any.whl

    标题"Python库 | django_admin_multilang-1.0-py3-none-any.whl"提到了一个Python库,名为`django_admin_multilang`,版本为1.0,它是一个适用于Python 3的软件包。`.whl`文件是一种预编译的Python轮子(wheel)包...

    高效易用Django流程引擎源码 - django-lb-workflow

    项目概述:django-lb-workflow 是一个基于Python的高效易用Django流程引擎源码,旨在轻松集成至现有系统。该项目主要由68个Python文件、30个HTML文件以及其他相关文件构成,共计136个文件。其中还包括了HTML模板、...

    django-python3-ldap, python 3的Django LDAP用户身份验证后端.zip

    django-python3-ldap, python 3的Django LDAP用户身份验证后端 django-python3-ldapdjango-python3-ldap 为 python 2和 3提供了一个 Django LDAP用户身份验证后端。特性使用LDAP服务器验证用户身份。将LDAP用户与...

    PyPI 官网下载 | Files.com-1.0.468-py3-none-any.whl

    《PyPI官网下载:Files.com-1.0.468-py3-none-any.whl——Python后端开发的关键资源》 在Python的世界里,PyPI(Python Package Index)是开发者们的重要宝库,它提供了丰富的第三方库和模块,极大地扩展了Python的...

    Python库 | djangocms_algolia-1.3.1.0-py3-none-any.whl

    资源分类:Python库 所属语言:Python 资源全名:djangocms_algolia-1.3.1.0-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    django-vue3-admin 基于RBAC模型的权限控制的一整套基础开发平台,权限粒度达到列级别,前后端分离

    django-vue3-admin 基于RBAC模型的权限控制的一整套基础开发平台,权限粒度达到列级别,前后端分离,后端采用django + django-rest-framework,前端采用基于 vue3 + CompositionAPI + typescript + vite + ele

    django3-cas-ng-4.0.0.tar.gz

    为支持django3对django_cas_ng进行修改 **Features** - Support CAS version 1.0, 2.0, 3.0 - Support Single Sign Out - Configuration of services via the django Admin application - Fine control on ...

    Python库 | bridgecrew-1.0.365-py3-none-any.whl

    "bridgecrew-1.0.365-py3-none-any.whl"是一个针对Python的库,它封装了特定的功能,以便开发者能够更方便地在他们的项目中实现这些功能。这个文件是Python的whl(wheel)格式,它是Python的二进制分发包,用于简化...

    django-admin-bootstrap-master.zip

    6. **安装与配置**:项目可能提供详细的文档,说明如何将这个主题集成到现有的Django项目中,包括安装依赖、配置settings以及注册admin应用。 通过使用这个项目,开发者不仅可以提升Django admin的视觉吸引力,还能...

    基于Django+Django -Rest-Framework+Python的在线考试系统后端(源码).zip

    1、基于Django+Django -Rest-Framework+Python的在线考试系统后端(源码).zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目...

    Django1.0速查手册_Django 1.0 Cheat sheet

    标签进一步明确了文档的主题是关于Django的速查手册或速查表(Cheat Sheet),这类文档通常会包含最常用的功能、语法和快捷方式等,方便用户在需要时快速查找。 #### 部分内容概述 下面将对部分内容中提及的关键...

    Django docs-1.11-en

    ### Django 1.11 文档概述与关键知识点解析 #### 一、文档概览 **标题**: Django docs-1.11-en **描述**: Django 官方文档,最新出炉 1.11 版本。 **标签**: Django **部分内容**: 该文档覆盖了 Django 1.11 的...

    PyPI 官网下载 | django_pumaska-1.0rc2-py3-none-any.whl

    标题中的“PyPI 官网下载 | django_pumaska-1.0rc2-py3-none-any.whl”指的是在Python的包索引服务(Python Package Index,简称PyPI)上发布的名为`django_pumaska`的软件包的1.0 release candidate 2版本。...

    django-classy-tags, 基于类的Django 模板标记.zip

    django-classy-tags, 基于类的Django 模板标记 django-classy-tags请参考文档/目录中的文档以获得帮助。 有关HTML呈现版本的信息,请参见这里的 。 这里项目这个项目的目标是创建一种新的编写 Django 模板标签的方法...

    Python库 | django_restql-0.3.1-py3-none-any.whl

    `django_restql`的核心功能是通过简化和扩展Django的`QuerySet` API,使开发者能够使用类似GraphQL的语法来查询数据库。它允许进行嵌套查询、过滤、排序和分页,同时保持性能高效。此外,`django_restql`还提供了...

Global site tag (gtag.js) - Google Analytics