ySJ
|
2.0/chapter11/#124 |
2010-04-19 15:51:05
|
<literal>object_detail</literal> 通用视图为context提供了出版商信息,但是看起来没有办法在模板中 获取 <emphasis>所有</emphasis> 出版商列表。
|
|
ySJ
|
2.0/chapter11/#123 |
2010-04-19 15:49:44
|
例如,考虑一下在每个出版商的详细页面显示所有其他出版商列表。
|
|
ySJ
|
2.0/chapter11/#115 |
2010-04-19 15:43:36
|
在模板中,通用视图会通过在<literal>template_object_name</literal>后追加一个<literal>_list</literal>的方式来创建一个表示列表项目的变量名。
|
|
ySJ
|
2.0/chapter11/#112 |
2010-04-19 15:39:18
|
我们可以很容易地像下面这样修改 <literal>template_object_name</literal> 参数的名称:
|
|
ySJ
|
2.0/chapter11/#110 |
2010-04-19 15:38:36
|
更好的变量名应该是<literal>publisher_list</literal>,这样变量所代表的内容就显而易见了。
|
|
ySJ
|
2.0/chapter11/#109 |
2010-04-19 15:38:20
|
他们必须知道这里正在处理的是书籍。
|
|
ySJ
|
2.0/chapter11/#108 |
2010-04-19 15:37:47
|
你也许已经注意到范例中的出版商列表模板在变量 <literal>object_list</literal> 里保存所有的书籍。这个方法工作的很好,只是对编写模板的人不太友好。
|
|
ySJ
|
2.0/chapter11/#103 |
2010-04-19 15:29:55
|
幸运的是,几乎每种情况都有相应的方法来简易地扩展通用视图以处理这些情况。
|
|
ySJ
|
2.0/chapter11/#85 |
2010-04-19 15:18:10
|
在这个例子中,这个推导出的模板名称将是 <literal>"books/publisher_list.html"</literal> ,其中books部分是定义这个模型的app的名称, publisher部分是这个模型名称的小写。
|
|
ySJ
|
2.0/chapter11/#84 |
2010-04-19 15:17:27
|
在缺少<literal>template_name</literal>的情况下,<literal>object_list</literal>通用视图将自动使用一个对象名称。
|
|
ySJ
|
2.0/chapter11/#81 |
2010-04-19 15:15:19
|
我们可以通过在额外参数字典中包含一个<literal>template_name</literal>键来显式地告诉<literal>object_list</literal>视图使用哪个模板:
|
|
ySJ
|
2.0/chapter11/#76 |
2010-04-19 15:12:45
|
要为所有的出版商创建一个列表页面,我们使用下面的URL配置:
|
|
ySJ
|
2.0/chapter11/#69 |
2010-04-19 15:12:15
|
因为这个应用实在太普遍了,Django带有很多内建的通用视图来帮助你很容易 地生成对象的列表和明细视图。
|
|
ySJ
|
2.0/chapter11/#68 |
2010-04-19 15:11:27
|
<literal>direct_to_template</literal> 毫无疑问是非常有用的,但Django通用视图最有用的地方是呈现数据库中的数据。
|
|
ySJ
|
2.0/chapter11/#56 |
2010-04-19 15:07:41
|
我们直接使用从客户端浏览器得到的数据构造模板名称(<literal>template="about/%s.html" % page</literal> )。乍看起来,这像是一个经典的 <emphasis>目录跨越(directory traversal)</emphasis> 攻击(详情请看第20章)。
|
|
ySJ
|
2.0/chapter11/#61 |
2010-04-19 15:07:16
|
<emphasis>是</emphasis> 从请求的URL中获取的,但并不是所有的值都会被接受。
|
|
ySJ
|
2.0/chapter11/#56 |
2010-04-19 15:06:29
|
我们直接使用从客户端浏览器得到的数据构造模板名称(<literal>template="about/%s.html" % page</literal> )。乍看起来,这像是一个经典的 <emphasis>目录遍历(directory traversal)</emphasis> 攻击(详情请看第20章)。
|
|
ySJ
|
2.0/chapter11/#51 |
2010-04-19 15:04:42
|
我们不希望一个不存在的模板导致一个服务端错误,所以我们捕获TemplateDoesNotExist异常并且返回404错误来作为替代。
|
|
ySJ
|
2.0/chapter11/#50 |
2010-04-19 15:03:39
|
这里唯一有点棘手的事情是要处理找不到模板的情况。
|
|
ySJ
|
2.0/chapter11/#49 |
2010-04-19 15:03:12
|
因为它返回一个<literal>HttpResponse</literal>对象,我们只需要简单的返回它就好了。
|
|
ySJ
|
2.0/chapter11/#48 |
2010-04-19 15:02:48
|
在这里我们象使用其他函数一样使用 <literal>direct_to_template</literal> 。
|
|
ySJ
|
2.0/chapter11/#42 |
2010-04-19 15:01:57
|
例如,我们扩展 about例子,把映射的URL从 <literal>/about//</literal>修改到一个静态渲染 <literal>about/.html</literal> 。 我们首先修改URL配置以指向新的视图函数:
|
|
ySJ
|
2.0/chapter11/#8 |
2010-04-19 14:49:35
|
Django的<emphasis>通用视图</emphasis> 可以减少这些痛苦。
|
|
ySJ
|
2.0/chapter10/#273 |
2010-04-19 14:43:52
|
下一张,我们将讲解Django的通用视图框架,使用它创建常见的网站可以节省时间。
|
|
ySJ
|
2.0/chapter10/#265 |
2010-04-19 14:42:32
|
比如,上面的例子可以被整合成一个自定义manager方法,就像这样:
|
|
ySJ
|
2.0/chapter10/#264 |
2010-04-19 14:41:46
|
不要把你的视图代码和django.db.connection语句混杂在一起,把它们放在自定义模型或者自定义manager方法中是个不错的主意。
|
|
ySJ
|
2.0/chapter10/#262 |
2010-04-19 14:40:50
|
如果你使用这项技术,数据库基础库将会自动添加引号,同时在必要的情况下转意你的参数。
|
|
ySJ
|
2.0/chapter10/#261 |
2010-04-19 14:39:36
|
如果你对Python DB-API不熟悉,请注意在cursor.execute()的SQL语句中使用"%s",而不要在SQL内直接添加参数。
|
|
ySJ
|
2.0/chapter10/#260 |
2010-04-19 14:38:33
|
connection和curso几乎实现了标准Python DB-API,你可以登录http://www.python.org/peps/pep-0249.html以了解更多。
|
|
ySJ
|
2.0/chapter10/#256 |
2010-04-19 14:37:05
|
然后,使用cursor.execute(sql, [params])来执行SQL语句,使用cursor.fetchone()或者cursor.fetchall(),返回记录集。
|
|
ySJ
|
2.0/chapter10/#255 |
2010-04-19 14:36:27
|
使用它,需要通过connection.cursor()得到一个游标对像。
|
|
ySJ
|
2.0/chapter10/#254 |
2010-04-19 14:34:51
|
你可以通过导入django.db.connection对像来轻松实现,它代表当前数据库连接。
|
|
ySJ
|
2.0/chapter10/#253 |
2010-04-19 14:34:25
|
有时候你会发现Django数据库API带给你的也只有这么多,那你可以为你的数据库写一些自定义SQL查询。
|
|
ySJ
|
2.0/chapter10/#251 |
2010-04-19 14:33:29
|
执行原始SQL查询。
|
|
ySJ
|
2.0/chapter10/#248 |
2010-04-19 14:33:00
|
这是用法的实例:
|
|
ySJ
|
2.0/chapter10/#245 |
2010-04-19 14:32:05
|
例子中的最后一个方法是一个property。
|
|
ySJ
|
2.0/chapter10/#242 |
2010-04-19 14:30:32
|
这个模型有一些自定义方法:
|
|
ySJ
|
2.0/chapter10/#241 |
2010-04-19 14:29:48
|
最好用例子来解释一下。
|
|
ySJ
|
2.0/chapter10/#239 |
2010-04-19 14:28:28
|
这是一项在模型的一个地方集中业务逻辑的技术。
|
|
ySJ
|
2.0/chapter10/#237 |
2010-04-19 14:27:06
|
有鉴于manager经常被用来用一些整表操作(table-wide),模型方法应该只对特殊模型实例起作用。
|
|
ySJ
|
2.0/chapter10/#236 |
2010-04-19 14:23:16
|
为了给你的对像添加一个行级功能,那就定义一个自定义方法。
|
|
ySJ
|
2.0/chapter10/#232 |
2010-04-19 14:22:39
|
结论是,你应该小心地选择你的默认manager。因为覆盖get_query_set()了,你可能接受到一个无用的返回对像,你必须避免这种情况。
|
|
ySJ
|
2.0/chapter10/#231 |
2010-04-19 14:21:06
|
Django将会把第一个manager定义为默认manager,Django的许多部分(但是不包括admin应用)将会明确地为模型使用这个manager。
|
|
ySJ
|
2.0/chapter10/#230 |
2010-04-19 14:19:31
|
如果你使用自定义的<literal>Manager</literal>对象,请注意,Django遇到的第一个Manager(以它在模型中被定义的位置为准)会有一个特殊状态。
|
|
ySJ
|
2.0/chapter10/#228 |
2010-04-19 14:16:16
|
这个例子允许你执行Person.men.all(),Person.women.all(),Person.people.all()查询,生成你想要的结果。
|
|
ySJ
|
2.0/chapter10/#223 |
2010-04-19 14:14:27
|
这是一个为模型添加通用滤器的简单方法。
|
|
ySJ
|
2.0/chapter10/#223 |
2010-04-19 14:14:19
|
这是一个为模型添加通过滤器的简单方法。
|
|
ySJ
|
2.0/chapter10/#222 |
2010-04-19 14:14:07
|
只要你愿意,你可以为你的模型添加多个manager()实例。
|
|
ySJ
|
2.0/chapter10/#221 |
2010-04-19 14:13:54
|
在同一个模型中使用多个manager。
|
|
ySJ
|
2.0/chapter10/#220 |
2010-04-19 14:13:45
|
这个例子也指出了其他有趣的技术:
|
|