辞書のレンダリング

□未翻訳

□翻訳中

□翻訳完了(Omi Chiba)

■レビュー(Yota Ichino)

辞書のレンダリング

HTML, XML, JSON

XML

JSON

次のアクションを考えてみてください:

Consider the following action:

1.

2.

3.

def count():

session.counter = (session.counter or 0) + 1

return dict(counter=session.counter, now=request.now)

このアクションは訪問者がページをリロードするたびに一つずつ増加されたcounterの値と、現在のページリクエストのタイムスタンプを返します。

This action returns a counter that is increased by one when a visitor reloads the page, and the timestamp of the current page request.

通常このページがリクエストされるのは:

Normally this page would be requested via:

http://127.0.0.1:8000/app/default/count

そしてHTMLでレンダリングされます。URLに拡張子を追加することで一つのコードも書かずにweb2pyに異なるプロトコルのページをレンダリングさせることができます。

and rendered in HTML. Without writing one line of code, we can ask web2py to render this page using a different protocols by adding an extension to the URL:

http://127.0.0.1:8000/app/default/count.html

http://127.0.0.1:8000/app/default/count.xml

http://127.0.0.1:8000/app/default/count.json

アクションによって返される辞書はそれぞれHTML、XML、JSONになります。

The dictionary returned by the action will be rendered in HTML, XML and JSON, respectively.

これがXMLの出力結果です:

Here is the XML output:

1.

2.

3.

4.

<document>

<counter>3</counter>

<now>2009-08-01 13:00:00</now>

</document>

これがJSONの出力結果です:

Here is the JSON output:

1.

{ 'counter':3, 'now':'2009-08-01 13:00:00' }

date、time、dateimeオブジェクトがISOフォーマットの文字列でレンダリングされている点に注意してください。これはJSONの標準機能というよりweb2pyの仕様です。

Notice that date, time, and datetime objects are rendered as strings in ISO format. This is not part of the JSON standard, but rather a web2py convention.

汎用ビュー

Generic Views

例えば".xml"拡張子が実行されたとき、web2pyは"default/count/xml"という名称のテンプレートファイルを参照し、見つからない場合は、"generic.xml"というテンプレートを参照します。"generic.html"、 "generic.xml"、 "generic.json"というファイルは雛形となるアプリケーションにて提供されていいます。それ以外の拡張子についてもユーザーによって簡単に定義可能です。

When, for example, the ".xml" extension is called, web2py looks for a template file called "default/count.xml", and if it does not find it, looks for a template called "generic.xml". The files "generic.html, "generic.xml", "generic.json" are provided with the current scaffolding application. Other extensions can be easily defined by the user.

web2pyアプリケーションでこれらを有効にするには特に何も必要ありません。古いweb2pyアプリケーションで使用するには、"generic.*"ファイルを新しい雛形アプリケーション(バージョン1.60移行)からコピーする必要があるかもしれません。

Nothing needs to be done to enable this in a web2py app. To use it in an older web2py app, you may need to copy the "generic.*" files from a later scaffolding app (after version 1.60).

これが"generic.html"のコードです

Here is the code for "generic.html"

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

{{extend 'layout.html'}}

{{=BEAUTIFY(response._vars)}}

<button onclick="document.location='{{=URL("admin","default","design",

args=request.application)}}'">admin</button>

<button onclick="jQuery('#request').slideToggle()">request</button>

<div class="hidden" id="request"><h2>request</h2>{{=BEAUTIFY(request)}}</div>

<button onclick="jQuery('#session').slideToggle()">session</button>

<div class="hidden" id="session"><h2>session</h2>{{=BEAUTIFY(session)}}</div>

<button onclick="jQuery('#response').slideToggle()">response</button>

<div class="hidden" id="response"><h2>response</h2>{{=BEAUTIFY(response)}}</div>

<script>jQuery('.hidden').hide();</script>

これが"generic.xml"のコードです

Here is the code for "generic.xml"

1.

2.

3.

4.

5.

6.

7.

8.

{{

try:

from gluon.serializers import xml

response.write(xml(response._vars),escape=False)

response.headers['Content-Type']='text/xml'

except:

raise HTTP(405,'no xml')

}}

そしてこれが"generic.json"のコードです

And here is the code for "generic.json"

1.

2.

3.

4.

5.

6.

7.

8.

{{

try:

from gluon.serializers import json

response.write(json(response._vars),escape=False)

response.headers['Content-Type']='text/json'

except:

raise HTTP(405,'no json')

}}

pythonの基本型(整数、浮動少数、文字、リスト、タプル、辞書)であればどのような辞書でもHTML、XML、JSONにレンダリングできます。response._varsはアクションによって返された辞書を含みます。

Any dictionary can be rendered in HTML, XML and JSON as long as it only contains python primitive types (int, float, string, list, tuple, dictionary). response._vars contains the dictionary returned by the action.

もしユーザー定義やweb2py独自のオブジェクトを辞書が含む場合は、カスタムビューにてレンダリングされる必要があります。

If the dictionary contains other user-defined or web2py-specific objects, they must be rendered by a custom view.

Rowsのレンダリング

Rendering Rows

as_list

select分によって返されたRowsセットをXMl、JSON、それ以外のフォーマットでレンダリングする必要がある場合は、まず始めにas_list()メソッドを利用してRowsオブジェクトを辞書のリストに変換します。

If you need to render a set of Rows as returned by a select in XML or JSON or another format, first transform the Rows object into a list of dictionaries using the as_list() method.

次の例を考えてみてください:

Consider for example the following mode:

1.

db.define_table('person', Field('name'))

次のアクションはHTMLにレンダリングできますがXMLやJSONにはできません:

The following action can be rendered in HTML, but not in XML or JSON:

1.

2.

3.

def everybody():

people = db().select(db.person.ALL)

return dict(people=people)

しかし次のアクションの場合はXMLとJSONにレンダリングできます:

while the following action can rendered in XML and JSON:

1.

2.

3.

def everybody():

people = db().select(db.person.ALL).as_list()

return dict(people=people)

カスタムフォーマット

Custom Formats

例えば、仮にPython pickle形式でアクションをレンダリングしたい場合は:

If, for example, you want to render an action as a Python pickle:

http://127.0.0.1:8000/app/default/count.pickle

単に以下のコードを含んだ"default/count.pickle"という新規ビューファイルを作成するだけでいいです:

you just need to create a new view file "default/count.pickle" that contains:

1.

2.

3.

4.

5.

{{

import cPickle

response.headers['Content-Type'] = 'application/python.pickle'

response.write(cPickle.dumps(response._vars),escape=False)

}}

もし任意のアクションをPickle化したファイルとしてレンダリングしたい場合は、上記のファイルを"generic.pickle"という名前で保存するだけでいいです。

If you want to be able to render any action as a pickled file, you need only to save the above file with the name "generic.pickle".

全てのオブジェクトがPickle化できるわけでは無く、また元のオブジェクトに戻せるわけではありません。Pythonの基本型とその組み合わせを利用する方が無難です。ファイルストリームやデータベース接続への参照を持たないオブジェクトは通常はPickle化できますが、全てのPickle化したオブジェクトのクラスが事前に定義されている環境でしかPickle化から戻すことができません。

Not all objects are pickleable, and not all pickled objects can be un-pickled. It is safe to stick to primitive Python objects and combinations of them. Objects that do not contain references to file streams or database connections are usually pickleable, but they can only be un-pickled in an environment where the classes of all pickled objects are already defined.

RSS

RSS

web2pyにはRSSフィードのアクションによって返された辞書の値をレンダリングできる"generic.rss"というビューがあります。

web2py includes a "generic.rss" view that can render the dictionary returned by the action as an RSS feed.

RSSフィードは固定のデータ構造(タイトル、リンク、説明、アイテム、等々)で動作するため、アクションによって返される辞書の値も適切な構造を持つ必要があります。

Because the RSS feeds have a fixed structure (title, link, description, items, etc.) then for this to work, the dictionary returned by the action must have the proper structure:

1.

2.

3.

4.

5.

{'title' : ",

'link' : ",

'description': ",

'created_on' : ",

'entries' : []}

そしてentries内のそれぞれのエントリが同じような構造を持ちます:

and each entry in entries must have the same similar structure:

1.

2.

3.

4.

{'title' : ",

'link' : ",

'description': ",

'created_on' : "}

例えば次のようなアクションはRSSフィードとしてレンダリングできます:

For example the following action can be rendered as an RSS feed:

1.

2.

3.

4.

5.

6.

7.

8.

9.

def feed():

return dict(title="my feed",

link="http://feed.example.com",

description="my first feed",

entries=[

dict(title="my feed",

link="http://feed.example.com",

description="my first feed")

])

以下のURLにアクセスするだけです:

by simply visiting the URL:

http://127.0.0.1:8000/app/default/feed.rss

別の方法として、次のモデルも考えられます:

Alternatively, assuming the following model:

1.

2.

3.

4.

5.

db.define_table('rss_entry',

Field('title'),

Field('link'),

Field('created_on','datetime'),

Field('description'))

次の方法もRSSフィードとしてレンダリングできます:

the following action can also be rendered as an RSS feed:

1.

2.

3.

4.

5.

def feed():

return dict(title="my feed",

link="http://feed.example.com",

description="my first feed",

entries=db().select(db.rss_entry.ALL).as_list())

Rowsオブジェクトのas_list()メソッドはrowsを辞書のリストに変換します。

The as_list() method of a Rows object converts the rows into a list of dictionaries.

ここで明記されていないkey名が辞書のリストに存在する場合は、無視されます。

If additional dictionary items are found with key names not explicitly listed here, they are ignored.

これがweb2pyで提供されている"generic.rss"ビューです:

Here is the "generic.rss" view provided by web2py:

1.

2.

3.

4.

5.

6.

7.

8.

{{

try:

from gluon.serializers import rss

response.write(rss(response._vars),escape=False)

response.headers['Content-Type']='application/rss+xml'

except:

raise HTTP(405,'no rss')

}}

もう一つのRSSアプリケーションの例として、"slashdot"フィードからデータを収集し新しいweb2py RSSフィードをレンダリングするRSSアグリゲーターを考えてみましょう。

As one more example of an RSS application, we consider an RSS aggregator that collects data from the "slashdot" feed and returns a new web2py rss feed.

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

def aggregator():

import gluon.contrib.feedparser as feedparser

d = feedparser.parse(

"http://rss.slashdot.org/Slashdot/slashdot/to")

return dict(title=d.channel.title,

link = d.channel.link,

description = d.channel.description,

created_on = request.now,

entries = [

dict(title = entry.title,

link = entry.link,

description = entry.description,

created_on = request.now) for entry in d.entries])

以下からアクセスできます:

It can be accessed at:

http://127.0.0.1:8000/app/default/aggregator.rss

CSV

CSV

Comma Separated Values (CSV)フォーマットは表形式のデータを表すプロトコルです。

The Comma Separated Values (CSV) format is a protocol to represent tabular data.

次のモデルを考えてみましょう:

Consider the following model:

1.

2.

3.

4.

db.define_model('animal',

Field('species'),

Field('genus'),

Field('family'))

そしてアクション:

and the following action:

1.

2.

3.

def animals():

animals = db().select(db.animal.ALL)

return dict(animals=animals)

web2pyには"generic.csv"が無いため、"default/animals.csv"というanimalsをCSVにシリアライズするカスタムビューを定義する必要があります。実装の例をあげると:

web2py does not provide a "generic.csv"; you must define a custom view "default/animals.csv" that serializes the animals into CSV. Here is a possible implementation:

1.

2.

3.

4.

5.

6.

7.

{{

import cStringIO

stream=cStringIO.StringIO()

animals.export_to_csv_file(stream)

response.headers['Content-Type']='application/vnd.ms-excel'

response.write(stream.getvalue(), escape=False)

}}

"generica.csv"を定義しておくことは可能ですが、シリアライズ化されるオブジェクト名(例の場合は"animals")が明示される必要があります。このため"generic.csv"ファイルはweb2pyで提供されていません。

Notice that one could also define a "generic.csv" file, but one would have to specify the name of the object to be serialized ("animals" in the example). This is why we do not provide a "generic.csv" file.