settings 文件内:python
DATABASES = { ' default ' : { ' ENGINE ' : ' django.db.backends.postgresql_psycopg2 ' , ' NAME ' : ' mydatabase ' , ' USER ' : ' mydatabaseuser ' , ' PASSWORD ' : ' mypassword ' , ' HOST ' : ' 127.0.0.1 ' , ' PORT ' : ' 5432 ' , } }
若是是 SQLite,则只需填写 engine 和 name,SQLite 的 name 应当包含可靠路径(由于没有 server):web
DATABASES = { ' default ' : { ' ENGINE ' : ' django.db.backends.sqlite3 ' , ' NAME ' : ' mydatabase ' , } }
测试数据库配置:sql
>>> from django.db import connection >>> cursor = connection.cursor()
django 的 ORM 示例,定义在 app 下的 models 文件内,具体支持的字段参考官方文档:shell
from django.db import models class Book(models.Model): title = models.CharField(max_length = 100 ) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField()
django 使用额外一张单独的表来管理多对多联系。数据库
在部署模型前,首先应保证相应的 app 是已安装状态,这在 settings 文件内的 INSTALLED_APPS 字段内进行设置。django
python manage.py validate
python manage.py sqlall books
这里的 books 是 app 的名称。运行后输出以下:安全
BEGIN ; CREATE TABLE "books_publisher" ( "id" serial NOT NULL PRIMARY KEY , "name" varchar ( 30 ) NOT NULL , "address" varchar ( 50 ) NOT NULL , "city" varchar ( 60 ) NOT NULL , "state_province" varchar ( 30 ) NOT NULL , "country" varchar ( 50 ) NOT NULL , "website" varchar ( 200 ) NOT NULL ) ; CREATE TABLE "books_author" ( "id" serial NOT NULL PRIMARY KEY , "first_name" varchar ( 30 ) NOT NULL , "last_name" varchar ( 40 ) NOT NULL , "email" varchar ( 75 ) NOT NULL ) ; CREATE TABLE "books_book" ( "id" serial NOT NULL PRIMARY KEY , "title" varchar ( 100 ) NOT NULL , "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id") DEFERRABLE INITIALLY DEFERRED, "publication_date" date NOT NULL ) ; CREATE TABLE "books_book_authors" ( "id" serial NOT NULL PRIMARY KEY , "book_id" integer NOT NULL REFERENCES "books_book" ("id") DEFERRABLE INITIALLY DEFERRED, "author_id" integer NOT NULL REFERENCES "books_author" ("id") DEFERRABLE INITIALLY DEFERRED, UNIQUE ("book_id", "author_id") ) ; CREATE INDEX "books_book_publisher_id" ON "books_book" ("publisher_id"); COMMIT ;
注意:app
python manage.py syncdb
在 python manage.py shell 命令行内执行 INSERT 操做的方法是实例化一个模型对象,并调用其 .save() 方法post
>>> from books.models import Publisher >>> p1 = Publisher(name = ' Apress ' , address = ' 2855 Telegraph Avenue ' , ... city = ' Berkeley ' , state_province = ' CA ' , country = ' U.S.A. ' , ... website = ' http://www.apress.com/ ' ) >>> p1.save()
不过这个 save() 方法在用于 UPDATE 功能时,实际执行的是更新整行而不只是修改过的属性。这可能会引发竞态条件,若是想只更新一个属性,应当调用结果集的 .update() 方法:测试
>>> Publisher.objects.filter(id = 52 ).update(name = ' Apress Publishing ' )
update() 方法返回一个整数,表示受影响的行数。
.delete() 方法与 .update() 相似,都是做用于结果集的方法。但出于安全考虑,在删除表中全部元组时,须要显示调用 .all() 方法:
>>> Publisher.objects.delete() Traceback (most recent call last): File " <console> " , line 1 , in < module > AttributeError: ' Manager ' object has no attribute ' delete ' >>> Publisher.objects.all().delete()
若是想 print 出 Publisher 对象的内容,须要在定义模型时写好 __str__() 方法。
>>> publisher_list = Publisher.objects.all() >>> publisher_list [ < Publisher: Publisher object > , < Publisher: Publisher object > ]
>>> Publisher.objects.filter(name = ' Apress ' [, *** ]) [ < Publisher: Apress > ]
注意这里是双下划线 __contains
>>> Publisher.objects.filter(name__contains = " press " ) [ < Publisher: Apress > ]
filter() 返回的老是一个容器对象,这个对象实现了列表的操做方法(一如既往不包括负索引),所以老是可使用好比 for 循环来迭代其中的元素。对应的有一个 get() 方法,这个方法要求知足条件的元素有且只有一个,不然引起异常。
>>> Publisher.objects.order_by( " state_province " , " address " )
第二个参数仅在第一个参数相同时起做用,排序还能够在属性前加“-”来实现逆序:
>>> Publisher.objects.order_by( " -name " )
.ordered_by() 可做用于结果查询结果对象集,因此 filter() 返回的结果也能够支持。
或者,直接在模型定义的地方指定默认排序方式:
class Publisher(models.Model): name = models.CharField(max_length = 30 ) . . . class Meta: ordering = [ ' name ' ]
当访问外键字段时,会获得相应的模型对象:
>>> b = Book.objects.get(id = 50 ) >>> b.publisher < Publisher: Apress Publishing > >>> b.publisher.website u ' http://www.apress.com/ '
而当经过外键反向追溯时,则会得到一个模型对象的 QuerySet,这个对象与前面同样也支持过滤和分切操做。实现这类访问使用的属性名是由模型名称的小写 + _set 组成的:
>>> p = Publisher.objects.get(name = ' Apress Publishing ' ) >>> p.book_set.all() [ < Book: The Django Book > , < Book: Dive Into Python > , ...] >>> p.book_set.filter(name__icontains = ' django ' ) [ < Book: The Django Book > , < Book: Pro Django > ]
多对多和外键工做方式相同,只不过处理的是QuerySet而不是模型实例:
>>> b = Book.objects.get(id = 50 ) >>> b.authors.all() [ < Author: Adrian Holovaty > , < Author: Jacob Kaplan - Moss > ] >>> b.authors.filter(first_name = ' Adrian ' ) [ < Author: Adrian Holovaty > ] >>> b.authors.filter(first_name = ' Adam ' ) []
反向查询也能够。 要查看一个做者的全部书籍,使用author.book_set ,就如这样:
>>> a = Author.objects.get(first_name = ' Adrian ' , last_name = ' Holovaty ' ) >>> a.book_set.all() [ < Book: The Django Book > , < Book: Adrian ' s Other Book>]
先前提到过,syncdb 命令只添加新表,并不会把已有模型的更新同步到数据库中。实际上,django 对已有 模型 与 数据库 之间的对应关系仅做最低限度的检查——即:模型中的字段在数据库中必须有,不然会引起运行时错误(在用户进行查询的时候);至于数据库中是否存在模型里并未定义的字段,django 并不关心,由于数据库中多余的字段并不影响 django 依据模型作正常的查询。(django 在作 orm 到 sql 语句的转化时,老是会明确指出要查询的字段)
基于这种逻辑,想要修改数据库模式应该采用的方法就是:在不引起运行时错误的前提下,按特定顺序分别修改数据库和模型。具体顺序为:
在形如 Book.objects.all() 的语句中,objects 做为 models.Model 类的一个特殊属性,他是 models.Manager 的实例。有些时候咱们能够经过自定义这个属性来实现一些特别的方法,或修改 manager 返回的 QuerySets 。
这须要子类化一个 Manager 对象,再把它绑定到具体的模型中,好比:
# models.py from django.db import models # ... Author and Publisher models here ... class BookManager(models.Manager): def title_count(self, keyword): return self.filter(title__icontains = keyword).count() class Book(models.Model): title = models.CharField(max_length = 100 ) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField() num_pages = models.IntegerField(blank = True, null = True) objects = BookManager() def __unicode__ (self): return self.title
有了这个manager,咱们如今能够这样作:
>>> Book.objects.title_count( ' django ' ) 4 >>> Book.objects.title_count( ' python ' ) 18
manager的基本QuerySet返回系统中的全部对象。 例如,`` Book.objects.all()`` 返回数据库book中的全部书本。咱们能够经过覆盖Manager.get_query_set()方法来重写manager的基本QuerySet。 get_query_set()按照你的要求返回一个QuerySet。
from django.db import models # First, define the Manager subclass. class DahlBookManager(models.Manager): def get_query_set(self): return super(DahlBookManager, self).get_query_set().filter(author = ' Roald Dahl ' ) # Then hook it into the Book model explicitly. class Book(models.Model): title = models.CharField(max_length = 100 ) author = models.CharField(max_length = 50 ) # ... objects = models.Manager() # The default manager. dahl_objects = DahlBookManager() # The Dahl-specific manager.
在这个示例模型中,Book.objects.all()返回了数据库中的全部书本,而Book.dahl_objects.all()只返回了Roald Dahl的书。
这个例子也说明了另一件事情,就是一个模型能够有多个 manager 属性。你只须要给他们作好命名就能够了(不要再用 objects)。
注意:django 会把模型中定义的第一个 manager 做为默认 manager 使用,若是你重写了任何一个 manager 的话。因此当你给模型添加 manager 的时候,必定记得在最前面把 models.Manager 绑定给 objects 。
模型方法就是模型里定义的方法,跟普通类里定义的方法没什么不一样。
使用 DB-API 便可。