5:向层次结构添加资源¶
每种类型有多个视图,允许在资源树的任何位置添加内容。
背景¶
我们现在有多种类型的东西,但是每个资源类型只有一个视图。我们需要能够向容器添加内容,然后查看和编辑资源。
We will use the previously mentioned concept of named views. A name is a part of the URL that appears after the resource identifier. 例如:
@view_config(context=Folder, name='add_document')
…表示此URL::
http://localhost:6543/some_folder/add_document
…将匹配正在配置的视图。就好像您有一个面向对象的Web,它对由URL表示的资源进行操作。
目标¶
允许在资源树中添加和编辑内容。
创建一个发布数据的简单表单。
创建获取发布数据、创建资源并重定向到新添加的资源的视图。
按类型创建命名视图。
步骤¶
我们将使用前面的步骤作为起点:
$ cd ..; cp -r typeviews addcontent; cd addcontent $ $VENV/bin/python setup.py develop
我们的观点
addcontent/tutorial/views.py
需要特定类型的注册:1from random import randint 2 3from pyramid.httpexceptions import HTTPFound 4from pyramid.location import lineage 5from pyramid.view import view_config 6 7from .resources import ( 8 Root, 9 Folder, 10 Document 11 ) 12 13 14class TutorialViews(object): 15 def __init__(self, context, request): 16 self.context = context 17 self.request = request 18 self.parents = reversed(list(lineage(context))) 19 20 @view_config(renderer='templates/root.jinja2', 21 context=Root) 22 def root(self): 23 page_title = 'Quick Tutorial: Root' 24 return dict(page_title=page_title) 25 26 @view_config(renderer='templates/folder.jinja2', 27 context=Folder) 28 def folder(self): 29 page_title = 'Quick Tutorial: Folder' 30 return dict(page_title=page_title) 31 32 @view_config(name='add_folder', context=Folder) 33 def add_folder(self): 34 # Make a new Folder 35 title = self.request.POST['folder_title'] 36 name = str(randint(0, 999999)) 37 new_folder = Folder(name, self.context, title) 38 self.context[name] = new_folder 39 40 # Redirect to the new folder 41 url = self.request.resource_url(new_folder) 42 return HTTPFound(location=url) 43 44 @view_config(name='add_document', context=Folder) 45 def add_document(self): 46 # Make a new Document 47 title = self.request.POST['document_title'] 48 name = str(randint(0, 999999)) 49 new_document = Document(name, self.context, title) 50 self.context[name] = new_document 51 52 # Redirect to the new document 53 url = self.request.resource_url(new_document) 54 return HTTPFound(location=url) 55 56 @view_config(renderer='templates/document.jinja2', 57 context=Document) 58 def document(self): 59 page_title = 'Quick Tutorial: Document' 60 return dict(page_title=page_title)
在中生成可重用的代码段
addcontent/tutorial/templates/addform.jinja2
添加内容:1<p> 2 <form class="form-inline" 3 action="{{ request.resource_url(context, 'add_folder') }}" 4 method="POST"> 5 <div class="form-group"> 6 <input class="form-control" name="folder_title" 7 placeholder="New folder title..."/> 8 </div> 9 <input type="submit" class="btn" value="Add Folder"/> 10 </form> 11</p> 12<p> 13 <form class="form-inline" 14 action="{{ request.resource_url(context, 'add_document') }}" 15 method="POST"> 16 <div class="form-group"> 17 <input class="form-control" name="document_title" 18 placeholder="New document title..."/> 19 </div> 20 <input type="submit" class="btn" value="Add Document"/> 21 </form> 22</p>
将此代码段添加到
addcontent/tutorial/templates/root.jinja2
:1{% extends "templates/layout.jinja2" %} 2{% block content %} 3 4 <h2>{{ context.title }}</h2> 5 <p>The root might have some other text.</p> 6 {% include "templates/contents.jinja2" %} 7 8 {% include "templates/addform.jinja2" %} 9 10{% endblock content %}
表格需要在
addcontent/tutorial/templates/folder.jinja2
:1{% extends "templates/layout.jinja2" %} 2{% block content %} 3 4 <h2>{{ context.title }}</h2> 5 {% include "templates/contents.jinja2" %} 6 7 {% include "templates/addform.jinja2" %} 8 9{% endblock content %}
$ $VENV/bin/nosetests
应报告正在运行4个测试。运行 Pyramid 应用程序时使用:
$ $VENV/bin/pserve development.ini --reload
在浏览器中打开http://localhost:6543/。
分析¶
现在我们的观点代表一个更丰富的系统,其中可以处理表单数据来修改树中的内容。我们通过将命名视图附加到资源类型,使它们成为面向对象操作的自然系统来实现这一点。
To mimic uniqueness, we randomly choose a satisfactorily large number. 为了真正的唯一性,我们还需要检查该数字是否已经存在于资源树的同一级别。
We'll start to address a couple of issues brought up in the Extra Credit below in the next step of this tutorial, 6:在ZODB中存储资源 .
Extra Credit¶
如果添加文件夹和文档,然后重新启动应用程序,会发生什么情况?
如果删除伪随机伪唯一命名约定并用固定值替换它,会发生什么情况?