(转)Django ====> models学习

转。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

五、数据库访问
1、基本数据访问
[root@pxe-svr mysite]# ./manage.py shell
>>> from books.models import Publisher
#导入Publisher模型类
>>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue', city='Berkeley', state_province='CA', country='U.S.A.',website='http://www.apress.com/')
#创建Publisher类的实例p1
>>> p1.save()
#调用实例p1的save()方法将数据存入数据库,Django 会在后台执行一条 INSERT 语句。
如果需要一步完成对象的创建与存储至数据库,就使用`` objects.create()`` 方法.
>>> p1 = Publisher.objects.create(name='Apress', address='2855 Telegraph Avenue', city='Berkeley', state_province='CA', country='U.S.A.',website='http://www.apress.com/')
获取
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Publisher object>]
2、添加模块的字符串表现
当我们打印整个publisher列表时,我们没有得到想要的有用信息,无法把````对象区分开来:
[root@pxe-svr mysite]# vim books/models.py
from django.db import models

# Create your models here.
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()

def __unicode__(self):
return self.name


class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()

def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)

class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()

def __unicode__(self):
return self.title
__unicode__() 方法可以进行任何处理来返回对一个对象的字符串表示。 Publisher和Book对象的__unicode__()方法简单地返回各自的名称和标题,
Author对象的__unicode__()方法则稍微复杂一些,它将first_name和last_name字段值以空格连接后再返回。
对__unicode__()的唯一要求就是它要返回一个unicode对象 如果`` __unicode__()`` 方法未返回一个Unicode对象,而返回比如说一个整型数字,
那么Python将抛出一个`` TypeError`` 错误,并提示:”coercing to Unicode: need string or buffer, int found” 。
unicode对象就是一个Python字符串.
Unicode对象并没有编码。它们使用Unicode,一个一致的,通用的字符编码集。 当你在Python中处理Unicode对象的时候,你可以直接将它们混合使用和互相匹配而不必去考虑编码细节。
Django 在其内部的各个方面都使用到了 Unicode 对象。 模型 对象中,检索匹配方面的操作使用的是 Unicode 对象,视图 函数之间的交互使用的是 Unicode 对象,
模板的渲染也是用的 Unicode 对象。通常,我们不必担心编码是否正确,后台会处理的很好。
为了让我们的修改生效,先退出Python Shell,然后再次运行 python manage.py shell 进入。(这是保证代码修改生效的最简单方法。)
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Apress>

3、插入和更新数据
1)插入
>>> from books.models import Publisher
>>> p = Publisher(name='Apress', address='2855 Telegraph Avenue', city='Berkeley', state_province='CA', country='U.S.A.',website='http://www.apress.com/')
>>> p.save()
>>> p.id
4L
#因为 Publisher 模型有一个自动增加的主键 id ,所以第一次调用 save() 还多做了一件事: 计算这个主键的值并把它赋值给这个对象实例:

>>> p = Publisher.objects.create(name='Apress', address='2855 Telegraph Avenue', city='Berkeley', state_province='CA', country='U.S.A.',website='http://www.apress.com/')
>>> p.id
5L
这个方法也会有实例属性id
2)更新
>>>p = Publisher.objects.get(name='Apress')
>>> p.name='jin'
>>> p.save
这里不爽的是需要原来创建的那个实例
执行的 save() 相当于下面的SQL语句:
UPDATE books_publisher SET
name = 'jin',
address = '2855 Telegraph Ave.',
city = 'Berkeley',
state_province = 'CA',
country = 'U.S.A.',
website = 'http://www.apress.com'
WHERE id = 5;
注意,并不是只更新修改过的那个字段,所有的字段都会被更新。 这个操作有可能引起竞态条件,这取决于你的应用程序。

3)更新多个对象
Django 模型的save()方法更新了不仅仅是name列的值,还有更新了所有的列。 若name以外的列有可能会被其他的进程所改动的情况下,只更改name列显然是更加明智的。
更改某一指定的列,我们可以调用结果集(QuerySet)对象的update()方法:
>>> Publisher.objects.filter(id=7).update(country='USA')
1L
等同
UPDATE books_publisher
SET country='USA'
WHERE id = 52;
update()方法会返回一个整型数值,表示受影响的记录条数。 在上面的例子中,这个值是2。
update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录

4、选择对象 查询
1)基本查询数据 Publisher.objects.all()
>>>Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]
QuerySet 对象,仿真列表
这相当于这个SQL语句:
SELECT id, name, address, city, state_province, country, website
FROM books_publisher;
注意到Django在选择所有数据时并没有使用 SELECT* ,而是显式列出了所有字段。
设计的时候就是这样: SELECT* 会更慢,而且最重要的是列出所有字段遵循了Python 界的一个信条: 明言胜于暗示。
Publisher.objects.all() 这行的每个部分:
首先,已定义的模型 Publisher
然后,是objects属性。 它被称为管理器
所有的模型都自动拥有一个 objects 管理器;你可以在想要查找数据时使用它。
最后,还有 all() 方法。这个方法返回返回数据库中所有的记录。 尽管这个对象 看起来 象一个列表(list),它实际是一个 QuerySet 对象, 这个对象是数据库中一些记录的集合。
所有的数据库查找都遵循这个通用模式:
2)数据过滤 Publisher.objects.filter()
>>> Publisher.objects.filter(name='jin')
[<Publisher: jin>]
filter() 根据关键字参数来转换成 WHERE SQL语句。
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE name = 'jin';
传递多个参数到 filter() 来缩小选取范围:
>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")
[<Publisher: jin>, <Publisher: Apress>]
多个参数会被转换成 AND SQL从句,
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE country = 'U.S.A.'
AND state_province = 'CA';
注意,SQL缺省的 = 操作符是精确匹配的
LIKE方式匹配
>>> Publisher.objects.filter(name__contains="press")
[<Publisher: Apress>]
在 name 和 contains 之间有双下划线。和Python一样,Django也使用双下划线来表明会进行一些魔术般的操作。这里,contains部分会被Django翻译成LIKE语句:
3)、获取单个对象。Publisher.objects.get()
上面的例子中`` filter()`` 函数返回一个记录集,这个记录集是一个列表。 相对列表来说,有些时候我们更需要获取单个的对象, `` get()`` 方法就是在此时使用的:
>>> Publisher.objects.get(name="Apress")
这样,就返回了单个对象,而不是列表(更准确的说,QuerySet)。 所以,如果结果是多个对象,会导致抛出异常:
<Publisher: Apress>
Publisher.objects.get(country="U.S.A.")
如果查询没有返回结果也会抛出异常:
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."
4)数据排序 Publisher.objects.order_by()
在你的 Django 应用中,你或许希望根据某字段的值对检索结果排序,比如说,按字母顺序。
>>> Publisher.objects.all()
[<Publisher: jin>, <Publisher: Apress>]
>>> Publisher.objects.order_by("name")
[<Publisher: Apress>, <Publisher: jin>]
SQL语句里多了指定排序的部分:
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
ORDER BY name;
对多个字段进行排序
Publisher.objects.order_by("state_province", "address")
还可以指定逆向排序,在前面加一个减号 - 前缀:
类似SQL :ORDER BY name DESC;
>>> Publisher.objects.order_by("-name")
[<Publisher: jin>, <Publisher: Apress>]

5)在模型的缺省排序方式
尽管很灵活,但是每次都要用 order_by() 显得有点啰嗦。 大多数时间你通常只会对某些 字段进行排序。 在这种情况下,Django让你可以指定模型的缺省排序方式:
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()

def __unicode__(self):
return self.name

class Meta:
rdering = ['name']
新的概念。 class Meta,内嵌于 Publisher 这个类的定义中(如果 class Publisher 是顶格的,那么 class Meta 在它之下要缩进4个空格--按 Python 的传统 )。
你可以在任意一个模型类中使用 Meta 类,来设置一些与特定模型相关的选项。
如果你设置了这个选项,那么除非你检索时特意额外地使用了 order_by(),否则,当你使用 Django 的数据库 API 去检索时,Publisher对象的相关返回值默认地都会按 name 字段排序。
>>> from books.models import Publisher
>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: jin>]

6)连锁查询Publisher.objects.filter().order_by() #过滤后再排序
我们已经知道如何对数据进行过滤和排序。 当然,通常我们需要同时进行过滤和排序查询的操作。 因此,你可以简单地写成这种“链式”的形式:
>>> Publisher.objects.filter(country="U.S.A.").order_by("-name")
[<Publisher: jin>, <Publisher: Apress>]
转换成SQL查询就是 WHERE 和 ORDER BY 的组合:
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE country = 'U.S.A'
ORDER BY name DESC;
7)限制返回的数据
另一个常用的需求就是取出固定数目的记录。可以使用标准的Python列表裁剪语句:
Publisher.objects.order_by('name')[0]
这相当于:
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
ORDER BY name
LIMIT 1;
类似的,可以用Python的range-slicing语法来取出数据的特定子集:
Publisher.objects.order_by('name')[0:2]
超出边界 不会报错
注意,不支持Python的负索引(negative slicing):
虽然不支持负索引,但是我们可以使用其他的方法。 比如,稍微修改 order_by() 语句来实现:
>>> Publisher.objects.order_by('-name')[0]

5、删除对象
删除数据库中的对象只需调用该对象的delete()方法即可:
>>> p = Publisher.objects.get(name="jin")
>>> p.delete()
>>> Publisher.objects.all()
[<Publisher: Apress>]
同样我们可以在结果集上调用delete()方法同时删除多条记录。这一点与我们上一小节提到的update()方法相似:
>>> Publisher.objects.filter(country='USA').delete() #有条件删除
>>> Publisher.objects.all().delete() #删除所有数据
>>> Publisher.objects.all()

posted @ 2012-12-24 16:24  事件轮询,回不到过去  阅读(4114)  评论(0编辑  收藏  举报