当前位置:K88软件开发文章中心网站服务器框架django → 文章内容

Django 模型高级进阶

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-25 14:19:20

le = 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) def __unicode__(self): return self.title(注意 阅读第六章的“设置可选字段”以及本章下面的“添加非空列”小节以了解我们在这里添加blank=True和null=True的原因。)然后,我们运行命令manage.py sqlall books 来查看CREATE TABLE语句。 语句的具体内容取决与你所使用的数据库, 大概是这个样子:CREATE TABLE "books_book" ( "id" serial NOT NULL PRIMARY KEY, "title" varchar(100) NOT NULL, "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id"), "publication_date" date NOT NULL, "num_pages" integer NULL);新加的字段被这样表示:"num_pages" integer NULL接下来,我们要在开发环境上运行数据库客户端,如果是PostgreSQL,运行 psql,,然后,我执行如下语句。ALTER TABLE books_book ADD COLUMN num_pages integer;添加 非NULL 字段这里有个微妙之处值得一提。 在我们添加字段num_pages的时候,我们使用了 blank=True 和 null=True 选项。 这是因为在我们第一次创建它的时候,这个数据库字段会含有空值。然而,想要添加不能含有空值的字段也是可以的。 要想实现这样的效果,你必须先创建 NULL 型的字段,然后将该字段的值填充为某个默认值,然后再将该字段改为 NOT NULL 型。 例如:BEGIN;ALTER TABLE books_book ADD COLUMN num_pages integer;UPDATE books_book SET num_pages=0;ALTER TABLE books_book ALTER COLUMN num_pages SET NOT NULL;COMMIT;如果你这样做,记得你不要在模型中添加 blank=True 和 null=True 选项。执行ALTER TABLE之后,我们要验证一下修改结果是否正确。启动python并执行下面的代码:>>> from mysite.books.models import Book>>> Book.objects.all()[:5]如果没有异常发生,我们将切换到生产服务器,然后在生产环境的数据库中执行命令ALTER TABLE 然后我们更新生产环境中的模型,最后重启web服务器。删除字段从Model中删除一个字段要比添加容易得多。 删除字段,仅仅只要以下几个步骤:删除字段,然后重新启动你的web服务器。用以下命令从数据库中删除字段:ALTER TABLE books_book DROP COLUMN num_pages;请保证操作的顺序正确。 如果你先从数据库中删除字段,Django将会立即抛出异常。删除多对多关联字段由于多对多关联字段不同于普通字段,所以删除操作是不同的。从你的模型中删除ManyToManyField,然后重启web服务器。用下面的命令从数据库删除关联表:DROP TABLE books_book_authors;像上面一样,注意操作的顺序。删除模型删除整个模型要比删除一个字段容易。 删除一个模型只要以下几个步骤:从文件中删除你想要删除的模型,然后重启web 服务器models.py然后用以下命令从数据库中删除表:DROP TABLE books_book;当你需要从数据库中删除任何有依赖的表时要注意(也就是任何与表books_book有外键的表 )。正如在前面部分,一定要按这样的顺序做。Managers在语句Book.objects.all()中,objects是一个特殊的属性,需要通过它查询数据库。 在第5章,我们只是简要地说这是模块的manager 。现在是时候深入了解managers是什么和如何使用了。总之,模块manager是一个对象,Django模块通过它进行数据库查询。 每个Django模块至少有一个manager,你可以创建自定义manager以定制数据库访问。下面是你创建自定义manager的两个原因: 增加额外的manager方法,和/或修manager返回的初始QuerySet。增加额外的Manager方法增加额外的manager方法是为模块添加表级功能的首选办法。 (至于行级功能,也就是只作用于模型对象实例的函数,一会儿将在本章后面解释。)例如,我们为Book模型定义了一个title_count()方法,它需要一个关键字,返回包含这个关键字的书的数量。 (这个例子有点牵强,不过它可以说明managers如何工作。)# models.pyfrom 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下面是编码该注意的一些地方:我们建立了一个BookManager类,它继承了django.db.models.Manager。这个类只有一个title_count()方法,用来做统计。 注意,这个方法使用了self.filter(),此处self指manager本身。我们把BookManager()赋值给模型的objects属性。 它将取代模型的默认manager(objects)如果我们没有特别定义,它将会被自动创建。 我们把它命名为objects,这是为了与自动创建的manager保持一致。为什么我们要添加一个title_count()方法呢?是为了将经常使用的查询进行封装,这样我们就不必重复编码了。修改初始Manager QuerySetsmanager的基本QuerySet返回系统中的所有对象。 例如,Book.objects.all() 返回数据库book中的所有书本。我们可以通过覆盖Manager.get_query_set()方法来重写manager的基本QuerySet。 get_query_set()按照你的要求返回一个QuerySet。例如,下面的模型有 两个 manager。一个返回所有对像,另一个只返回作者是Roald Dahl的书。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.cl

上一页  [1] [2] [3]  下一页


Django 模型高级进阶