- 创建项目:django-admin.py startproject project_name
-
python manage.py help 查看所有命令集
-
但是,系统对app有一个约定: 如果你使用了Django的数据库层(模型),你 必须创建一个django app。 模型必须存放在apps中
- python manage.py startapp app_name
-
用下面的命令对校验模型的有效性:python manage.py validate
-
sqlall 命令并没有在数据库中真正创建数据表,只是把SQL语句段打印出来: python manage.py sqlall books
执行这些SQL语句,运行 syncdb 命令:python manage.py syncdb- syncdb 命令是同步你的模型到数据库的一个简单方法。它会根据 INSTALLED_APPS 里设置的app来检查数据库, 如果表不存在,它就会创建它。
- 需要注意的是, syncdb 并 不能 同步模型的修改到数据库。如果你修改了模型,然后你想更新 数据库, syncdb是帮不了你的
- 如果你再次运行 python manage.py syncdb ,什么也没发生,因为你没有添加新的模型或者 添加新的app
-
只需要添加一个方法
__str__()
到 Publisher 对象。__str__()
方法告诉Python要怎样把对象当作字符串来使用 -
__str()__
也是一个很好的例子来演示我们怎么添加 行为 到模型里。 Django的模型不只是为对象定义了数据库表的结构,还定义了对象的行为。__str__()
就是一个例子来演示模型知道怎么显示它们自己 -
Publisher.objects.all()
这行的每个部分: -
objects 是干什么的?技术上,它是一个 管理器(manager) 。 管理器 将在附录B详细描述,在这里你只要知道它处理有关数据表的操作,特别是数据查找。
-
所有的模型都自动拥有一个 objects 管理器;你可以在想要查找数据时是使用它。管理器的名称是可以自己更改的
-
最后,还有 all() 方法。这是 objects 管理器返回所有记录的一个方法。 尽管这个对象 看起来象一个列表(list),它实际是一个 QuerySet 对象, 这个对象是数据库中一些记录的集合。附录C将详细描述QuerySet,现在,我们 就先当它是一 个仿真列表对象好了。
-
QuerySet 代表了你的数据库中的对象的一个集合。它根据所给参数可以构造若干个 过滤器 来缩小这个集合的规模。用SQL术语来讲,一个 QuerySet 就相当于一个 SELECT 语句,过滤器相当于诸如 WHERE 或者 LIMIT 的限定语。对一个模块来讲, Manager 是 QuerySets 的主要来源。它就像一个根本的 QuerySet ,可以对模块的数据库表中的所有对象进行描述。比如,
Blog.objects
就是包含着数据库中所有的 Blog 对象的一个根本的 QuerySet 。 -
每次都要用 order_by() 显得有点啰嗦。 大多数时间你通常只会对某些 字段进行排序。在这种情况下,Django让你可以指定模型的缺省排序方式:
class Meta: ordering = ["name"]
-
这个 ordering = ["name"] 告诉Django如果没有显示提供 order_by() , 就缺省按名称排序
-
Meta是什么?
- Django使用内部类Meta存放用于附加描述该模型的元数据,查看附录B,在Meta项下面,获得更多选项信息
-
你的模型的每个字段应该是一个适当的 Field 类的实例,Django使用这个字段类的类型去确定如下内容:
- 数据库列类型(如 INTEGER 、 VARCHAR )。
- 在Django的admin界面中使用的部件,如果你想要指定的话.(例如:
<input type="text"><select>
) - 用于Django的admin界面的基本的合法性验证。
通用字段选项
- 模型的Metadata选项:
- db_table -- 模型对应的数据库表的名字
- ordering -- 对象默认的排序方法,获取对象列表时会用到 ordering = ['-title']
- permissions --创建对象时,需要额外加入权限表的权限
- verbose_name -- 对象的友好可读名称(单数形式)
管理器:
- Manager 是提供给Django模型的数据库查询接口。Django程序的每个模型中至少存在一个 Manager
- 管理器默认名称为 objects, people = models.Manager() 可通过定义修改
URLconf 技巧
- URLconf 中为某个特别的模式指定视图函数:你可以传入一个包含模块名和函数名的字符串,而不是函数对象本身
- 应该使用带引号的 'mysite.views.current_datetime' 而不是 mysite.views.current_datetime当使用字符串技术时,你可以采用更简化的方式:提取出一个公共视图前缀。在我们的 URLconf 例子中,每一个视图字符串都是以 'mysite.views' 开始的,造成过多的输入。我们可以提取出公共前缀然后把它作为第一个参数传给 patterns()
urlpatterns = patterns('mysite.views',
(r'^now/$', 'current_datetime'),
(r'^now/plus(\d{1,2})hours/$', 'hours_ahead'),
(r'^now/minus(\d{1,2})hours/$', 'hours_behind'),
(r'^now/in_chicago/$', 'now_in_chicago'),
(r'^now/in_london/$', 'now_in_london'),
)
- urls.py 文件中 patterns()对象可以有很多个,需要叠加处理,如下示例:
urlpatterns = patterns() urlpatterns += patterns()
- url正则表达式中获取参数可以使用()
(r'^articles/(\d{4})/$', views.year_archive)
- 也可以使用命名正则表达式:命名的正则表达式组的语法是 (?P<name>pattern) ,这里 name 是组的名字,而 pattern 是匹配的某个模式
(r'^articles/(?P<year>\d{4})/$', views.year_archive),
-
理解匹配/分组算法:
- 需要注意的是如果在URLconf中使用命名组,那么命名组和非命名组是不能同时存在于同一个URLconf的模式中的。如果你这样做,Django不会抛出任何错误,但你可能会发现你的URL并没有像你预想的那样匹配正确。
- 具体地,以下是URLconf解释器有关正则表达式中命名组和非命名组所遵循的算法。
- 如果有任何命名的组,Django会忽略非命名组而直接使用命名组。
- 否则,Django会把所有非命名组以位置参数的形式传递。
- 在以上的两种情况,Django同时会以关键字参数的方式传递一些额外参数。更具体的信息可参考下一节。
-
伪造捕捉到的URLconf值
-
你可能会想增加这样一个URL, /mydata/birthday/ , 这个URL等价于 /mydata/jan/06/ 。这时你可以这样利用额外URLconf参数
(r'^mydata/birthday/$', views.my_view, {'month': 'jan', 'day': '06'}),
-
通过使用额外的URLconf参数,给视图函数传递额外参数
# urls.py from django.conf.urls.defaults import * from mysite import models, views urlpatterns = patterns('', (r'^events/$', views.object_list, {'model': models.Event}), (r'^blog/entries/$', views.object_list, {'model': models.BlogEntry}), ) # views.py from django.shortcuts import render_to_response def object_list(request, model): obj_list = model.objects.all() template_name = 'mysite/%s_list.html' % model.__name__.lower() return render_to_response(template_name, {'object_list': obj_list})
-
我们通过 model 参数直接传递了模型类。额外URLconf参数的字典是可以传递任何类型的对象,而不仅仅只是字符串。
-
这一行: model.objects.all() 是 鸭子界定 (原文:duck typing,是计算机科学中一种动态类型判断的概念)的一个例子:如果一只鸟走起来像鸭子,叫起来像鸭子,那我们就可以把它当作是鸭子了。需要注意的是代码并不知道 model 对象的类型是什么;它只要求 model 有一个 objects 属性,而这个属性有一个 all() 方法。
-
了解捕捉值和额外参数之间的优先级
(r'^mydata/(?P<id>\d+)/$', views.my_view, {'id': 3}),
-
当冲突出现的时候,额外URLconf参数优先于捕捉值。也就是说,如果URLconf捕捉到的一个命名组变量和一个额外URLconf参数包含的变量同名时,额外URLconf参数的值会被使用。
-
每个被捕获的参数将被作为纯Python字符串来发送,而不管正则表达式中的格式
-
短路逻辑
urlpatterns = patterns('',
...
('^auth/user/add/$', 'django.contrib.admin.views.auth.user_add_stage'),
('^([^/]+)/([^/]+)/add/$', 'django.contrib.admin.views.main.add_stage'),
...
)
-
在这种情况下,象 /auth/user/add/ 的请求将会被 user_add_stage 视图处理。尽管URL也匹配第二种模式,它会先匹配上面的模式。(这是短路逻辑)
-
当一个请求进来时,Django试着将请求的URL作为一个普通Python字符串进行URLconf模式匹配(而不是作为一个Unicode字符串
-
包含其他URLconf include()
urlpatterns = patterns('', (r'^weblog/', include('mysite.blog.urls')), (r'^photos/', include('mysite.photos.urls')), (r'^about/$', 'mysite.views.about'), )
-
指向 include() 的正则表达式并 不 包含一个 $ (字符串结尾匹配符),但是包含了一个斜杆。每当Django遇到 include() 时,它将截断匹配的URL,并把剩余的字符串发往包含的URLconf作进一步处理。
-
被捕获的参数总是传递到被包含的URLconf中的每一行,不管那些行对应的视图是否需要这些参数
-
额外的选项参数将总是被传递到被包含的URLconf中的每一行,不管那一行对应的视图是否确实作为有效参数接收这些选项
深入模板引擎
- 自定义过滤器
from django import template
register = template.Library()
@register.filter(name='cut')
def cut(value, arg):
return value.replace(arg, '')
-
自定义模板标签
- 编写编译函数
from django import template def do_current_time(parser, token): try: # split_contents() knows not to split quoted strings. tag_name, format_string = token.split_contents() except ValueError: msg = '%r tag requires a single argument' % token.contents[0] raise template.TemplateSyntaxError(msg) return CurrentTimeNode(format_string[1:-1])
- 编写模板节点
import datetime class CurrentTimeNode(template.Node): def __init__(self, format_string): self.format_string = format_string def render(self, context): now = datetime.datetime.now() return now.strftime(self.format_string)
- 注册标签
from django import template register = template.Library() register.tag('current_time', do_current_time)
- 或者使用装饰器注册,方法同过滤器一样
-
编写自定义模板加载器
未完待续.....
网友评论