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

Django 模型进阶

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

icode() 就是一个例子来演示模型知道怎么显示它们自己。插入和更新数据你已经知道怎么做了: 先使用一些关键参数创建对象实例,如下:>>> p = Publisher(name='Apress',... address='2855 Telegraph Ave.',... city='Berkeley',... state_province='CA',... country='U.S.A.',... website='http://www.apress.com/')这个对象实例并 没有 对数据库做修改。 在调用save() 方法之前,记录并没有保存至数据库,像这样:>>> p.save()在SQL里,这大致可以转换成这样:INSERT INTO books_publisher (name, address, city, state_province, country, website)VALUES ('Apress', '2855 Telegraph Ave.', 'Berkeley', 'CA', 'U.S.A.', 'http://www.apress.com/');因为 Publisher 模型有一个自动增加的主键 id ,所以第一次调用 save() 还多做了一件事: 计算这个主键的值并把它赋值给这个对象实例:>>> p.id52 # this will differ based on your own data接下来再调用 save() 将不会创建新的记录,而只是修改记录内容(也就是 执行 UPDATE SQL语句,而不是INSERT 语句):>>> p.name = 'Apress Publishing'>>> p.save()前面执行的 save() 相当于下面的SQL语句:UPDATE books_publisher SET name = 'Apress Publishing', address = '2855 Telegraph Ave.', city = 'Berkeley', state_province = 'CA', country = 'U.S.A.', website = 'http://www.apress.com'WHERE id = 52;注意,并不是只更新修改过的那个字段,所有的字段都会被更新。 这个操作有可能引起竞态条件,这取决于你的应用程序。 请参阅后面的“更新多个对象”小节以了解如何实现这种轻量的修改(只修改对象的部分字段)。UPDATE books_publisher SET name = 'Apress Publishing'WHERE id=52;选择对象当然,创建新的数据库,并更新之中的数据是必要的,但是,对于 Web 应用程序来说,更多的时候是在检索查询数据库。 我们已经知道如何从一个给定的模型中取出所有记录:>>> Publisher.objects.all()[<Publisher: Apress>, <Publisher: O'Reilly>]这相当于这个SQL语句:SELECT id, name, address, city, state_province, country, websiteFROM books_publisher;注意注意到Django在选择所有数据时并没有使用 SELECT ,而是显式列出了所有字段。 设计的时候就是这样:SELECT 会更慢,而且最重要的是列出所有字段遵循了Python 界的一个信条: 明言胜于暗示。有关Python之禅(戒律) :-),在Python提示行输入 import this 试试看。让我们来仔细看看 Publisher.objects.all() 这行的每个部分:首先,我们有一个已定义的模型 Publisher 。没什么好奇怪的: 你想要查找数据, 你就用模型来获得数据。然后,是objects属性。 它被称为管理器,我们将在第10章中详细讨论它。 目前,我们只需了解管理器管理着所有针对数据包含、还有最重要的数据查询的表格级操作。所有的模型都自动拥有一个 objects 管理器;你可以在想要查找数据时使用它。最后,还有 all() 方法。这个方法返回返回数据库中所有的记录。 尽管这个对象 看起来 象一个列表(list),它实际是一个 QuerySet 对象, 这个对象是数据库中一些记录的集合。 附录C将详细描述QuerySet。 现在,我们就先当它是一个仿真列表对象好了。所有的数据库查找都遵循一个通用模式:数据过滤我们很少会一次性从数据库中取出所有的数据;通常都只针对一部分数据进行操作。 在Django API中,我们可以使用filter() 方法对数据进行过滤:>>> Publisher.objects.filter(name='Apress')[<Publisher: Apress>]filter() 根据关键字参数来转换成 WHERE SQL语句。 前面这个例子 相当于这样:SELECT id, name, address, city, state_province, country, websiteFROM books_publisherWHERE name = 'Apress';你可以传递多个参数到 filter() 来缩小选取范围:>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")[<Publisher: Apress>]多个参数会被转换成 AND SQL从句, 因此上面的代码可以转化成这样:SELECT id, name, address, city, state_province, country, websiteFROM books_publisherWHERE country = 'U.S.A.'AND state_province = 'CA';注意,SQL缺省的 = 操作符是精确匹配的, 其他类型的查找也可以使用:>>> Publisher.objects.filter(name__contains="press")[<Publisher: Apress>]在 name 和 contains 之间有双下划线。和Python一样,Django也使用双下划线来表明会进行一些魔术般的操作。这里,contains部分会被Django翻译成LIKE语句:SELECT id, name, address, city, state_province, country, websiteFROM books_publisherWHERE name LIKE '%press%';其他的一些查找类型有:icontains(大小写无关的LIKE),startswith和endswith, 还有range(SQLBETWEEN查询)。 附录C详细描述了所有的查找类型。获取单个对象上面的例子中filter() 函数返回一个记录集,这个记录集是一个列表。 相对列表来说,有些时候我们更需要获取单个的对象, get() 方法就是在此时使用的:>>> Publisher.objects.get(name="Apress")<Publisher: Apress>这样,就返回了单个对象,而不是列表(更准确的说,QuerySet)。 所以,如果结果是多个对象,会导致抛出异常:Publisher.objects.get(country="U.S.A.")Traceback (most recent call last):...MultipleObjectsReturned: get() returned more than one Publisher --it returned 2! Lookup parameters were {'country': 'U.S.A.'}如果查询没有返回结果也会抛出异常:>>> Publisher.objects.get(name="Penguin")Traceback (most recent call last): ...DoesNotExist: Publisher matching query does not exist.这个 DoesNotExist 异常 是 Publisher 这个 model 类的一个属性,即 Publisher.DoesNotExist。在你的应用中,你可以捕获并处理这个异常,像这样:try: p = Publisher.objects.get(name='Apress')except Publisher.DoesNotExist: print "Apress isn't in the database yet."else: print "Apress is in the database."数据排序在运行前面的例子中,你可能已经注意到返回的结果是无序的。 我们还没有告诉数据库 怎样对结果进行排序,所以我们返回的结果是无序的。在你的 Django 应用中,你或许希望根据某字段的值对检索结果排序,比如说,

上一页  [1] [2] [3] [4] [5] [6] [7] [8]  下一页


Django 模型进阶