全部博文(2065)
分类: Python/Ruby
2009-08-04 10:05:30
修改表结构也就是按照正确的顺序修改各种Python代码和数据库本身(如果你需要修改表结构的话就要这样处理了。手工修改PYTHON代码与数据库本身)
9.1添加字段
先在数据库中添加列,然后再改变模型中对应的字段。首先,在开发环境中执行下面的步骤(也就是说,不是在发布服务器上):
把这个字段添加到你的模型中.(第一步:定义到模型层中去新增一个字段出来)
运行 manage.py sqlall [yourapp] 会看到模型的新的 CREATE TABLE 语句。注意新的字段的列定义。(查看到具体的SQL语句)
启动您的数据库交互shell(也就是 psql 或 mysql , 或者您也可以使用 manage.py dbshell )。 执行一个 ALTER TABLE 语句,添加您的新列。
4. (可选)用 manage.py shell 启动Python交互式shell,并通过引入模型并选择表验证新的字段已被正确添加(比如, MyModel.objects.all()[:5] )。
删除、修改字段都是一样的操作。先修改模型层的代码然后再为了减少数据库访问次数,每个 QuerySet 包含一个缓存,要写出高效的代码,理解这一点很重要。
在刚被创建的 QuerySet 中,缓存是空的。当 QuerySet 第一次被赋值,就是执行数据库查询的时候,Django会把查询结果保存到这个 QuerySet 的缓存中,并返回请求结果(例如, QuerySet 迭代结束的时候,就会返回下一条记录)。再次使用 QuerySet 的值的话会重复使用缓存中的内容。
非常地跟memecherad相似哦!
实现的方法如下:
queryset = Poll.objects.all() #得到一个queryset数据集能够存在缓存
print [p.headline for p in queryset] # Evaluate the query set.
4.过滤器
加一些过滤条件。用 filter() 和 exclude() 方法可以实现这样的功能
5.级联过滤器
对我们的结果集进一步过滤处理!
细化过的 QuerySet 本身就是一个 QuerySet ,所以可以进一步细化。
>>> qs = Entry.objects.filter(headline__startswith='What')
会得到一个结果集出来!
>>> qs = qs..exclude(pub_date__gte=datetime.datetime.now())
在此基础上进一步过滤处理!
6.限量查询集
可以用Python的数据切片的语法来限定 QuerySet 的结果数量,这和SQL中的 LIMIT 和 OFFSET 语句是一样的。
比如,这句返回前五个条目( LIMIT 5 ):
>>> Entry.objects.all()[:5]
返回一个新的 QuerySet ,包含匹配参数lookup的对象。
返回一个新的 QuerySet ,包含不匹配参数kwargs的对象。
默认情况下,会返回一个按照models的metadata中的``ordering``选项排序的``QuerySet``(请查看附录B)。你可以调用``order_by()``方法按照一个特定的规则进行排序以覆盖默认的行为:
要使用随机的顺序,使用 "?" ,比如:
>>> Entry.objects.order_by('?') 随机排序处理操作!
7.select_related()
e = Entry.objects.get(id=5)
b = e.blog 这样的话还会再去请求一次数据库服务器的!
如果这样写的:e = Entry.objects.select_related().get(id=5)
然后:
b = e.blog 就不会再去请求服务器了!
1.
这个快捷的方法可以一次性完成创建并保证对象。它让你完成了下面两个步骤:
>>> p = Person(first_name="Bruce", last_name="Springsteen")
>>> p.save()
into a single line:
>>> p = Person.objects.create(first_name="Bruce", last_name="Springsteen")>>> Blog.objects.get(id__exact=14) # Explicit form
传统的方法是通过
1.构造出来对象
2.调用save方法处理。现在不用直接使用create即可!
try:
obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
obj.save()
为了不保存重复的记录可以这样处理哦!
这种方法如可以使用如下的方法代替出来!
obj, created = Person.objects.get_or_create(
first_name = 'John',
last_name = 'Lennon',
defaults = {'birthday': date(1940, 10, 9)}
)
2.count()
返回记录集的个数。即QuerySet的个数!
Entry.objects.count()
Entry.objects.filter(headline__contains='Lennon').count()
可以返回当前数据集的记录条数!
相当于: SELECT COUNT(*)
3.latest(field_name=None)
Entry.objects.latest('pub_date')
能够查询出来最新的记录!
4.exact
执行严格区分大小写的内容包含检测:
Entry.objects.get(headline__contains='Lennon')
这将会匹配标题为``’Today Lennon honored’`` 的,而不匹配 ‘today lennon honored’。
执行一个忽略大小写的内容包含检测:
>>> Entry.objects.get(headline__icontains='Lennon')
与``contains``不同, icontains 会 匹配 'today lennon honored' 。
这些即大于,大于或等于,小于,小于或等于:
>>> Entry.objects.filter(id__gt=4)
>>> Entry.objects.filter(id__lt=15)
>>> Entry.objects.filter(id__gte=0)
过滤的时候使用的逻辑连接词
筛选出包含在给定列表中的数据:
Entry.objects.filter(id__in=[1, 3, 4])
这会返回所有ID为1,3,或4的条目。
区分大小写的开头匹配:
>>> Entry.objects.filter(headline__startswith='Will')
这将返回标题Will he run?和Willbur named judge,但是不会返回Who is Will? 和will found in crypt.
Performs a case-insensitive starts-with:
>>> Entry.objects.filter(headline__istartswith='will')
Performs an inclusive range check:
>>> start_date = datetime.date(2005, 1, 1) >>> end_date = datetime.date(2005, 3, 31) >>> Entry.objects.filter(pub_date__range=(start_date, end_date))使用``True``或``False``,则分别相当于SQL语句中的``IS NULL``和``IS NOT NULL``:
>>> Entry.objects.filter(pub_date__isnull=True)
如果你需要写一个SQL查询,但是用Django的数据库映射来实现的话太复杂了,那么你可以考虑使用原始的SQL语句。
解决这个问题的比较好的方法是,给模块写一个自定义的方法或者管理器方法来执行查询。尽管在Django中,数据库查询在模块中没有任何存在的 必要性 ,但是这种解决方案使你的数据访问在逻辑上保持一致,而且从组织代码的角度讲也更灵活。操作指南见附录B。
最后,请记住Django的数据库层仅仅是访问数据库的一个接口,你可以通过其他的工具、编程语言或者数据库框架来访问数据库,它并不是特定于Django使用的。
可以考虑使用ORM也可以使用原生SQL语句!