<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8017294613983746080</id><updated>2024-11-15T20:12:55.069+09:00</updated><category term="web2py"/><category term="Django"/><category term="Google AppEngine"/><category term="Python"/><category term="Kay"/><category term="SyntaxHighlighter"/><category term="OpenID/OAuth/etc"/><category term="その他"/><category term="Golang"/><category term="Sphinx"/><category term="画像ポップアップ"/><category term="TypeScript"/><title type='text'>今日のPython</title><subtitle type='html'>Python中心に、日々発生する疑問点や解決策を記録していきます。&#xa;内容が間違っていたらゴメンね。&lt;br&gt;&#xa;（ このブログは目次を用意しています。記事をお探しの際は、ご利用ください。 ）</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://todayspython.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>122</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-8350745637604986432</id><published>2018-09-15T20:05:00.000+09:00</published><updated>2018-09-15T20:46:10.441+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="TypeScript"/><title type='text'>VSCode で TypeScript のデバック設定</title><content type='html'>VSCode (Visual Stadio Code)　で TypeScript  デバックするための設定は、ネット上で情報がたくさんあるのですが、なぜか少しずつ違っています。そして、動作しなかったりします。
&lt;p&gt;
今回は、単純なコードをデバックできるだけの設定をメモ書きします。


&lt;h5&gt;事前準備&lt;/h5&gt;
&lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;Visual Stadio Code&lt;/a&gt;、&lt;a href=&quot;https://www.typescriptlang.org/&quot;&gt;TypeScript&lt;/a&gt;、&lt;a href=&quot;https://nodejs.org/ja/&quot;&gt;Node.js&lt;/a&gt; がインストールされていることを確認します。

&lt;p&gt;
VSCode バージョン確認
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; code -v
&lt;span class=&quot;go&quot;&gt;1.27.1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5944e81f3c46a3938a82c701f96d7a59b074cfdc&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;x64&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
TypeScript バージョン確認
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; tsc -v
&lt;span class=&quot;go&quot;&gt;Version 3.0.3&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
Node.js バージョン確認
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; node -v
&lt;span class=&quot;go&quot;&gt;v10.10.0&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
確認できない場合、インストール作業を行ってください。インストール方法はネット上でいろいろ説明がありますが、次のページなどを参考にしてください。
&lt;br&gt;
&lt;a href=&quot;https://qiita.com/ochiochi/items/efdaa0ae7d8c972c8103&quot;&gt;TypeScriptチュートリアル① -環境構築編-&lt;/a&gt;

&lt;p&gt;
もしインストール中にVSCodeを開いていたら、一旦終了し開き直したほうが良いでしょう。




&lt;p&gt;&lt;br&gt;
今回のサンプル用として、次のコードを使用します。

&lt;div class=&quot;highligh&quot; style=&quot;background: #ffffff; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #ffffff;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;class&lt;/span&gt; Startup {
    &lt;span style=&quot;font-weight: bold&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;font-weight: bold&quot;&gt;static&lt;/span&gt; main(): &lt;span style=&quot;font-weight: bold&quot;&gt;number&lt;/span&gt; {
        console.log(&lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;#x27;Hello World&amp;#x27;&lt;/span&gt;);
        &lt;span style=&quot;font-weight: bold&quot;&gt;return&lt;/span&gt; 0;
    }
}
Startup.main();
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;


ファイル名 sample.ts とします。


&lt;h5&gt;コンパイル設定&lt;/h5&gt;

TypeScriptのコードをデバックするためにはコードをコンパイルし、JavaScriptファイル（xxx.js）とソースマップファイル（xxx.map）を生成する必要があります。もちろん手動でコンパイルしても大丈夫ですが、せっかくなので、VSCodeに自動でコンパイルさせるための設定をします。

&lt;ol&gt;
&lt;li&gt;コンパイルオプション指定
&lt;p&gt;
コンパイルオプションの設定ファイル（tsconfig.json）を作成します。tsconfig.json は TypeScript のファイルで、プロジェクトのルートディレクトリに置きます。
&lt;p&gt;
新規にファイルを作成し、次のように記述します。最後に、tsconfig.json という名前で保存します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;compilerOptions&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;target&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;es5&amp;quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;module&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;commonjs&amp;quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;sourceMap&amp;quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&quot;sourceMap&quot;: true によってコンパイル時、ソースマップファイルが生成されます。

&lt;p&gt;
この設定でコンパイルが実行可能かと思います。
&lt;p&gt;
VSCode メニューの 「ターミナル」→「ビルドタスクの実行」→「tsc:ビルド」 を選択すると、 js及びmapファイルが生成されるのが確認できます
（「tsc:ウォッチ」 を選択するとタスクが常駐し、tsソースが保存される度にコンパイルが実行されます ）。

&lt;/li&gt;

&lt;p&gt;&lt;br&gt;
&lt;li&gt;VSCode タスク設定
&lt;p&gt;
VSCodeから条件に応じて、処理を実行する機能が「タスク」です。今回はデバック時に事前に、TypeScriptコードをコンパイルするためのタスクを設定します。&lt;br&gt;

タスク設定には幾つも方法があるようですが、例えば次のようにします。

&lt;p&gt;
メニューの「ターミナル」→「タスクの構成」→「テンプレートからtasks.jsonを生成」を選択し、「tsc:ビルド」 を選んで tasks.json を生成させます。

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdBm7gRE1DllOMEDvM2Ml-JY9YDtbin6SsR4lz-NZqTZdqLyhcK8QdcTSnoms-8c55MnxpguCp1qtDL3_InYi4GZufEosWLtcI-6ioiWvSb60GI9IIQnHHv6EzeW16DtT9zZVX0nJpX4g/s1600/Sep-14-2018+04-59-30.gif&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdBm7gRE1DllOMEDvM2Ml-JY9YDtbin6SsR4lz-NZqTZdqLyhcK8QdcTSnoms-8c55MnxpguCp1qtDL3_InYi4GZufEosWLtcI-6ioiWvSb60GI9IIQnHHv6EzeW16DtT9zZVX0nJpX4g/s640/Sep-14-2018+04-59-30.gif&quot; width=&quot;640&quot; height=&quot;264&quot; data-original-width=&quot;976&quot; data-original-height=&quot;402&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
「コマンドパレット」 に、 &lt;span style=&quot;background-color:bisque; padding:0 5px 0 5px;&quot;&gt;&gt;tasks configure task&lt;/span&gt; と入力してもタスク構成にアクセス可能です。
&lt;br&gt;
要は、.vscode/tasks.json を生成することが必要な訳です。
&lt;p&gt;
生成したtasks.jsonファイルの内容は以下の通りですが、特にコードの変更は必要ありませんが、&lt;strong&gt;label&lt;/strong&gt; で名前（８行目）だけ付けておきます。

&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// See https://go.microsoft.com/fwlink/?LinkId=733558&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// for the documentation about the tasks.json format&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;2.0.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;tasks&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;typescript&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;            &lt;span class=&quot;s2&quot;&gt;&amp;quot;label&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;tsc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;            &lt;span class=&quot;s2&quot;&gt;&amp;quot;tsconfig&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;tsconfig.json&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;problemMatcher&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;s2&quot;&gt;&amp;quot;$tsc&amp;quot;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;



&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
以上で、デバック構成設定前の準備が完了です。

&lt;p&gt;&lt;br&gt;
余談ですが、TypeScriptのコードはコンパイルしなくても実行可能です。その場合、右クリックメニューの 「Run Code」 で実行できますが、事前に ts-node モジュールをインストールしておく必要があります。
&lt;br&gt;
ターミナルから次のようにインストールします。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; npm install -g ts-node
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;


&lt;h5&gt;デバッグ設定&lt;/h5&gt;

デバックでは構成ファイル（launch.json）を準備する必要があります。

&lt;p&gt;
VSCodeのメニューの 「デバック」→「構成を開く」 を選択し、「Node.js」を選ぶと launch.js が生成されます。

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6SfB1y5IohQZrw54we2DVwBcJvUJ6j9OIG9CNEwO_bWk65S_ESkBBe2cZRtMQLMN8oAJH4jbdLHIbiSf4CxrYbqmgD-v_qOEhndIrzaoKwu4yWqpS1NPWJ1ggnW-42g0rOub1Leab2QU/s1600/Sep-14-2018+08-04-38.gif&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6SfB1y5IohQZrw54we2DVwBcJvUJ6j9OIG9CNEwO_bWk65S_ESkBBe2cZRtMQLMN8oAJH4jbdLHIbiSf4CxrYbqmgD-v_qOEhndIrzaoKwu4yWqpS1NPWJ1ggnW-42g0rOub1Leab2QU/s640/Sep-14-2018+08-04-38.gif&quot; width=&quot;640&quot; height=&quot;264&quot; data-original-width=&quot;976&quot; data-original-height=&quot;402&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
「コマンドパレット」 に、 &lt;span style=&quot;background-color:bisque; padding:0 5px 0 5px;&quot;&gt;&gt;debug open launch.json&lt;/span&gt; と入力しても同様な事が可能です。

&lt;p&gt;
生成された launch.json のコードです。

&lt;div class=&quot;highligh&quot; style=&quot;background: #ffffff; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #ffffff;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span&gt;&lt;/span&gt;{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;version&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;0.2.0&amp;quot;&lt;/span&gt;,
    &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;configurations&amp;quot;&lt;/span&gt;: [
        {
            &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;type&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;node&amp;quot;&lt;/span&gt;,
            &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;request&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;launch&amp;quot;&lt;/span&gt;,
            &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;プログラムの起動&amp;quot;&lt;/span&gt;,
            &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;program&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;${&lt;/span&gt;&lt;span style=&quot;color: #666666; font-weight: bold; font-style: italic&quot;&gt;workspaceFolder&lt;/span&gt;&lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;}/sample.ts&amp;quot;&lt;/span&gt;,
            &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;outFiles&amp;quot;&lt;/span&gt;: [
                &lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;&amp;quot;${&lt;/span&gt;&lt;span style=&quot;color: #666666; font-weight: bold; font-style: italic&quot;&gt;workspaceFolder&lt;/span&gt;&lt;span style=&quot;color: #666666; font-style: italic&quot;&gt;}/**/*.js&amp;quot;&lt;/span&gt;
            ]
        }
    ]
}
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
これを次のように変更します。

&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: ....
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;version&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;0.2.0&amp;quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;configurations&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;type&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;node&amp;quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;request&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;launch&amp;quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;プログラムの起動&amp;quot;&lt;/span&gt;,
&lt;span class=&quot;hll&quot;&gt;            &lt;span class=&quot;s2&quot;&gt;&amp;quot;preLaunchTask&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;tsc&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;            &lt;span class=&quot;s2&quot;&gt;&amp;quot;program&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;workspaceFolder&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;fileBasenameNoExtension&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.ts&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;            &lt;span class=&quot;s2&quot;&gt;&amp;quot;smartStep&amp;quot;&lt;/span&gt;: true,
&lt;/span&gt;            &lt;span class=&quot;s2&quot;&gt;&amp;quot;outFiles&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;workspaceFolder&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/**/*.js&amp;quot;&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
変更は三点です。

&lt;dl&gt;
&lt;dt&gt;&lt;strong&gt;preLaunchTask&lt;/strong&gt; （１１行目）&lt;/dt&gt;
&lt;dd&gt;
デバッグセッションの開始前に起動するタスクを指定します。&lt;br&gt;
ここでは先程コンパイル設定で作成したタスクのラベル名(&quot;tsc&quot;)を指定します。
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;program&lt;/strong&gt; （１２行目）&lt;/dt&gt;
&lt;dd&gt;
デバッガを起動するときに起動する実行可能ファイルを指定します。&lt;br&gt;
自動生成されコードでは特定のファイル名を指定していましたが、${fileBasenameNoExtension} という記述に変更しました。${fileBasenameNoExtension} は現在開いているファイル名から拡張子を除いた文字列を返します。つまり、作業ディレクトリ上なら任意のソースファイルをデバックできることになります。
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;smartStep&lt;/strong&gt; （１３行目）&lt;/dt&gt;
&lt;dd&gt;
true の場合、マップファイル対象外のコードのステップを省略します。デバック中変な js コードが表示されたりしますが、それを省きます。ただ完全ではないようです。状況に応じて、&quot;skipFiles&quot; パラメータでスキップするソースを指定することが必要かもしれません。
&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;
preLaunchTask の設定ではなく、コンパイル設定でも紹介した、VSCode メニューの 「ターミナル」→「ビルドタスクの実行」→「tsc:ウォッチ」 でも同じように変更時にコンパイルされます（VSCode起動時にウォッチを実行する必要はありますが・・・）。


&lt;h5&gt;デバック実行とその他&lt;/h5&gt;

以上でVSCodeの設定が完了したので、デバックを実行してみます。

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOJG_kCIQkLA5FTINZcksNnvwOepMMjqTzI2F6YWVz0XzlH6h2K4OxTx5dSS1n-UysN1A-E0Ud-Qfa3oi49wsECrnrFhIE3hRufbknoTyi1ougyEqgKLom4-4KA341t_WBH_ET0ZQ1Cys/s1600/Sep-15-2018+04-53-45.gif&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOJG_kCIQkLA5FTINZcksNnvwOepMMjqTzI2F6YWVz0XzlH6h2K4OxTx5dSS1n-UysN1A-E0Ud-Qfa3oi49wsECrnrFhIE3hRufbknoTyi1ougyEqgKLom4-4KA341t_WBH_ET0ZQ1Cys/s640/Sep-15-2018+04-53-45.gif&quot; width=&quot;640&quot; height=&quot;310&quot; data-original-width=&quot;992&quot; data-original-height=&quot;480&quot; /&gt;&lt;/a&gt;

&lt;br clear=&quot;left&quot;&gt;

一応、動作するのが確認できました。

&lt;p&gt;
この他に、TypeScriptファイルとJavaScriptファイルが同じディレクトリにありますが、それぞれ別のディレクトリに配置する設定を考えてみます。

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNAmtwy0_EIZEYHQcUgGBzsGBi40cq89KKmoEpDJt9S2QzRJhYhpDfG5xIk2SRTqZzAzzMn8fllMruzBciVogva7wvgq5lg0vWJHAs3_Jt7Pj_QzP6x1UE5AhG96B-37heyCsZv8j9USk/s1600/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2018-09-15+6.54.03.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNAmtwy0_EIZEYHQcUgGBzsGBi40cq89KKmoEpDJt9S2QzRJhYhpDfG5xIk2SRTqZzAzzMn8fllMruzBciVogva7wvgq5lg0vWJHAs3_Jt7Pj_QzP6x1UE5AhG96B-37heyCsZv8j9USk/s1600/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2018-09-15+6.54.03.png&quot; data-original-width=&quot;232&quot; data-original-height=&quot;218&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

TypeScriptファイルは src に、JavaScript と map ファイルは build に配置します。

&lt;br clear=&quot;left&quot;&gt;

まず tsconfig.json ですが、次のように、&lt;strong&gt;outDir&lt;/strong&gt; パラメータでコンパイル時の出力先を指定します（６行目）。

&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;compilerOptions&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;target&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;es5&amp;quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;module&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;commonjs&amp;quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;sourceMap&amp;quot;&lt;/span&gt;: true,
&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;s2&quot;&gt;&amp;quot;outDir&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;build&amp;quot;&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
次に launch.json ですが、&lt;strong&gt;program&lt;/strong&gt; パラメータに TypeScriptファイルのディレクトリを（１３行目）、&lt;strong&gt;outFiles&lt;/strong&gt;にJavaScriptのディレクトリを指定します（１６行目）。

&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: ....
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;version&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;0.2.0&amp;quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;configurations&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;type&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;node&amp;quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;request&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;launch&amp;quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;プログラムの起動&amp;quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;preLaunchTask&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;tsc&amp;quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;program&amp;quot;&lt;/span&gt;: 
&lt;span class=&quot;hll&quot;&gt;                &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;workspaceFolder&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/src/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;fileBasenameNoExtension&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.ts&amp;quot;&lt;/span&gt;,
&lt;/span&gt;            &lt;span class=&quot;s2&quot;&gt;&amp;quot;smartStep&amp;quot;&lt;/span&gt;: true,
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;outFiles&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;                &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;workspaceFolder&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/build/**/*.js&amp;quot;&lt;/span&gt;
&lt;/span&gt;            &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

以上で、ディレクトリを分けてもデバックが動作すると思います。

&lt;p&gt;
参考：&lt;br&gt;
&lt;a href=&quot;https://qiita.com/TsuyoshiUshio@github/items/9879ea04cdd606982a65&quot;&gt;VSCode + Typescript でデバッグを有効にする&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://qiita.com/ttoonnaa/items/cb6a898e1f94a2692d14&quot;&gt;VisualStudioCode + TypeScript でブレークポイントが効かなかった問題（解決）&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://vscode-doc-jp.github.io/&quot;&gt;Visual Studio Code (VS Code) の非公式日本語訳&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://code.visualstudio.com/docs&quot;&gt;Visual Studio Code Docs&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;http://www.atmarkit.co.jp/ait/articles/1708/04/news027.html&quot;&gt;第2回　Visual Studio Codeのデバッグ構成ファイルの基本：Node.js編&lt;/a&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8350745637604986432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8350745637604986432'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2018/09/vscode-typescript.html' title='VSCode で TypeScript のデバック設定'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdBm7gRE1DllOMEDvM2Ml-JY9YDtbin6SsR4lz-NZqTZdqLyhcK8QdcTSnoms-8c55MnxpguCp1qtDL3_InYi4GZufEosWLtcI-6ioiWvSb60GI9IIQnHHv6EzeW16DtT9zZVX0nJpX4g/s72-c/Sep-14-2018+04-59-30.gif" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-4250367828564258313</id><published>2017-11-17T05:33:00.001+09:00</published><updated>2017-11-17T05:43:48.629+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google AppEngine"/><title type='text'>Datastore と組み込みインデックス</title><content type='html'>GoogleCloudFlatform（GoogleAppEngine）のNoSQLデータベースである、&lt;strong&gt;Datastore&lt;/strong&gt;を使用していると、奇妙なことに気づくと思います。それは、想定していた保存データ量に比べて、課金時に算出されたデータ量が大幅に多いという点です。ここで、Datastoreの料金を示してみます。


&lt;p&gt;
※ 米国／ヨーロッパ - &lt;a href=&quot;https://cloud.google.com/datastore/docs/pricing?hl=ja&quot; target=&quot;_blank&quot;&gt;Cloud Datastore 料金と割り当て&lt;/a&gt;&lt;br&gt;
&lt;table  border=&quot;1&quot; bordercolor=&quot;#B0B0B0&quot; cellpadding=&quot;3&quot; cellspacing=&quot;0&quot;&gt;
  &lt;thead  align=&quot;left&quot; bgcolor=&quot;#d0d0d0&quot;&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;1 日あたりの&lt;br&gt;無料利用枠&lt;/th&gt;
      &lt;th&gt;無料利用枠を&lt;br&gt;超えた場合の料金（単価）&lt;/th&gt;
      &lt;th&gt;料金&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody  align=&quot;left&quot;&gt;
    &lt;tr&gt;
      &lt;th&gt;保存データ&lt;/th&gt;
      &lt;td&gt;1 GB ストレージ&lt;/td&gt;
      &lt;td cloud-pricer=&quot;&quot; region=&quot;ctrl.region&quot; rate=&quot;ctrl.rate&quot; us-hourly=&quot;$0.18&quot; ja-hourly=&quot;$0.23&quot; class=&quot;ng-isolate-scope&quot;&gt;$0.18&lt;/td&gt;
      &lt;td&gt;GB/月&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;エンティティの読み込み数&lt;/th&gt;
      &lt;td&gt;50,000&lt;/td&gt;
      &lt;td cloud-pricer=&quot;&quot; region=&quot;ctrl.region&quot; rate=&quot;ctrl.rate&quot; us-hourly=&quot;$0.06&quot; ja-hourly=&quot;$0.08&quot; class=&quot;ng-isolate-scope&quot;&gt;$0.06&lt;/td&gt;
      &lt;td&gt;/10 万エンティティ&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;エンティティの書き込み数&lt;/th&gt;
      &lt;td&gt;20,000&lt;/td&gt;
      &lt;td cloud-pricer=&quot;&quot; region=&quot;ctrl.region&quot; rate=&quot;ctrl.rate&quot; us-hourly=&quot;$0.18&quot; ja-hourly=&quot;$0.23&quot; class=&quot;ng-isolate-scope&quot;&gt;$0.18&lt;/td&gt;
      &lt;td&gt;/10 万エンティティ&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;エンティティの削除数&lt;/th&gt;
      &lt;td&gt;20,000&lt;/td&gt;
      &lt;td cloud-pricer=&quot;&quot; region=&quot;ctrl.region&quot; rate=&quot;ctrl.rate&quot; us-hourly=&quot;$0.02&quot; ja-hourly=&quot;$0.03&quot; class=&quot;ng-isolate-scope&quot;&gt;$0.02&lt;/td&gt;
      &lt;td&gt;/10 万エンティティ&lt;/td&gt;
    &lt;/tr&gt;&lt;tr&gt;
      &lt;th&gt;小規模な操作&lt;/th&gt;
      &lt;td&gt;無制限&lt;/td&gt;
      &lt;td&gt;無料&lt;/td&gt;
      &lt;td&gt;-&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;
料金的には読み込み数や書き込み数の方が通常は大きいと思いますが、いつの間にか保存データが何十GB・何百GBとなり、課金されている場合があります。


&lt;h5&gt;保存データが増大する要因&lt;/h5&gt;

アプリケーションの設計時に、事前にデータ量を推定していると思います。しかし何十・何百GBと、想定外のデータが増えるのでしょうか？。
一例を挙げてみましょう。

&lt;p&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRwOfgE07ZvxhpvxGO7eYbjO1gGMu02sv6Ck8EL6nsSmJxErERSMJ49xJSSCEzS8rjv6p2dAZKGIG7xEEI5FXOSQbcUXbdhJf-IxD5QZleEkhuyEtN1mPjbc5nCiJ9sLqprGzLK1WAJto/s1600/%25E3%2583%2586%25E3%2582%2599%25E3%2583%25BC%25E3%2582%25BF%25E3%2582%25B9%25E3%2583%2588%25E3%2582%25A2_%25E3%2582%25BF%25E3%2582%2599%25E3%2583%2583%25E3%2582%25B7%25E3%2583%25A5%25E3%2583%259B%25E3%2582%2599%25E3%2583%25BC%25E3%2583%2588%25E3%2582%2599_-_hima-click.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRwOfgE07ZvxhpvxGO7eYbjO1gGMu02sv6Ck8EL6nsSmJxErERSMJ49xJSSCEzS8rjv6p2dAZKGIG7xEEI5FXOSQbcUXbdhJf-IxD5QZleEkhuyEtN1mPjbc5nCiJ9sLqprGzLK1WAJto/s640/%25E3%2583%2586%25E3%2582%2599%25E3%2583%25BC%25E3%2582%25BF%25E3%2582%25B9%25E3%2583%2588%25E3%2582%25A2_%25E3%2582%25BF%25E3%2582%2599%25E3%2583%2583%25E3%2582%25B7%25E3%2583%25A5%25E3%2583%259B%25E3%2582%2599%25E3%2583%25BC%25E3%2583%2588%25E3%2582%2599_-_hima-click.jpg&quot; width=&quot;640&quot; height=&quot;391&quot; data-original-width=&quot;1194&quot; data-original-height=&quot;729&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
あるエンティティのデータ使用状況（&lt;a href=&quot;https://console.cloud.google.com/datastore/stats&quot; target=&quot;_blank&quot;&gt;データストア・ダッシュボード&lt;/a&gt;）です。全体で８０MBを使用していますが、エンティティ（実データ）は、１０MBしかありません。残り７０MBを使用しているのが、&lt;strong&gt;組み込みインデックス&lt;/strong&gt;と呼ばれるデータです。

&lt;p&gt;
GoogleCloudPlatformのドキュメントには、次のように記述されています。

&lt;p&gt;
&lt;blockquote&gt;
インデックスは次の 2 種類に分けられます。
&lt;dl&gt;
&lt;dt&gt;&lt;a id=&quot;built_in_indexes&quot;&gt;&lt;/a&gt;&lt;em&gt;組み込みインデックス&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;デフォルトでは、エンティティの種類ごとに各プロパティのインデックスが自動的に事前定義されます。このような単一プロパティのインデックスは単純な種類のクエリに適しています。&lt;/dd&gt;
&lt;dt&gt;&lt;a id=&quot;composite_indexes&quot;&gt;&lt;/a&gt;&lt;em&gt;複合インデックス&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;複合インデックスでは、インデックス付けされたエンティティごとに複数のプロパティ値がインデックス付けされます。複雑なクエリをサポートする複合インデックスは、&lt;a href=&quot;https://cloud.google.com/datastore/docs/tools/indexconfig?hl=ja&quot;&gt;インデックス設定ファイル&lt;/a&gt;（&lt;code&gt;index.yaml&lt;/code&gt;）で定義されます。&lt;/dd&gt;
&lt;/dl&gt;
参考：&lt;a href=&quot;https://cloud.google.com/datastore/docs/concepts/indexes?hl=ja&quot; target=&quot;_blank&quot;&gt;インデックス&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;
組み込みインデックスは複合インデックスとは違い、自動で生成されるインデックスです。しかし、実データの７倍ものデータ（このデータの場合）を生成するのも問題ですね。

&lt;h5&gt;組み込みインデックスを生成しない&lt;/h5&gt;

&lt;p&gt;
組み込みインデックスを生成しないためには、エンティティ定義時にプロパティのパラメータとして、indexed=False を設定すればよいです。


&lt;blockquote&gt;

You declare a property unindexed by setting &lt;code&gt;indexed=False&lt;/code&gt; in the
&lt;a href=&quot;https://cloud.google.com/appengine/docs/standard/python/datastore/propertyclass#Property&quot;&gt;property constructor&lt;/a&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint notranslate&quot; translate=&quot;no&quot;&gt;&lt;div class=&quot;devsite-code-button-wrapper&quot;&gt;&lt;div class=&quot;devsite-code-button gc-analytics-event material-icons devsite-dark-code-button&quot; data-category=&quot;Site-Wide Custom Events&quot; data-label=&quot;Dark Code Toggle&quot; track-type=&quot;exampleCode&quot; track-name=&quot;darkCodeToggle&quot; data-tooltip-align=&quot;b,c&quot; data-tooltip=&quot;コードをダークテーマで表示&quot; aria-label=&quot;コードをダークテーマで表示&quot; data-title=&quot;コードをダークテーマで表示&quot;&gt;&lt;/div&gt;&lt;div class=&quot;devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button&quot; data-category=&quot;Site-Wide Custom Events&quot; data-label=&quot;Click To Copy&quot; track-type=&quot;exampleCode&quot; track-name=&quot;clickToCopy&quot; data-tooltip-align=&quot;b,c&quot; data-tooltip=&quot;クリックするとコピーできます&quot; aria-label=&quot;クリックするとコピーできます&quot; data-title=&quot;クリックするとコピーできます&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;code&gt;&lt;span class=&quot;kwd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;&lt;br&gt;&amp;nbsp; name &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; db&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;StringProperty&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;&lt;br&gt;&amp;nbsp; age &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; db&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;IntegerProperty&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;indexed&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can later change the property back to indexed by calling the constructor
again with &lt;code&gt;indexed=True&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint notranslate&quot; translate=&quot;no&quot;&gt;&lt;div class=&quot;devsite-code-button-wrapper&quot;&gt;&lt;div class=&quot;devsite-code-button gc-analytics-event material-icons devsite-dark-code-button&quot; data-category=&quot;Site-Wide Custom Events&quot; data-label=&quot;Dark Code Toggle&quot; track-type=&quot;exampleCode&quot; track-name=&quot;darkCodeToggle&quot; data-tooltip-align=&quot;b,c&quot; data-tooltip=&quot;コードをダークテーマで表示&quot; aria-label=&quot;コードをダークテーマで表示&quot; data-title=&quot;コードをダークテーマで表示&quot;&gt;&lt;/div&gt;&lt;div class=&quot;devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button&quot; data-category=&quot;Site-Wide Custom Events&quot; data-label=&quot;Click To Copy&quot; track-type=&quot;exampleCode&quot; track-name=&quot;clickToCopy&quot; data-tooltip-align=&quot;b,c&quot; data-tooltip=&quot;クリックするとコピーできます&quot; aria-label=&quot;クリックするとコピーできます&quot; data-title=&quot;クリックするとコピーできます&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;code&gt;&lt;span class=&quot;kwd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;&lt;br&gt;&amp;nbsp; name &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; db&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;StringProperty&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;&lt;br&gt;&amp;nbsp; age &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; db&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;IntegerProperty&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;indexed&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

参考： &lt;a href=&quot;https://cloud.google.com/appengine/docs/standard/python/datastore/indexes&quot; target=&quot;_blank&quot;&gt;Cloud Datastore Indexes&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;
NDBでモデル定義する場合は、次のようにプロパティのパラメータとして記述します。indexed=Falseを記述しない場合は、indexed=Trueの見做され、インデックスが生成されます。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StringProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IntegerProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;indexed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
pydal（web2pyフレームワーク)で記述する場合は、フィールドの&lt;strong&gt;custom_qualifier&lt;/strong&gt;パラメータに辞書形式で指定します。指定しない場合は、インデックスが生成されます。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;define_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#x27;person&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#x27;name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#x27;age&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#x27;integer&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;custom_qualifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#x27;indexed&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;


&lt;h5&gt;組み込みインデックス設定の注意点&lt;/h5&gt;

&lt;p&gt;
組み込みインデックスを生成しないという indexed=False は、どのプロパティ（フィールド）に対して設定してよいという訳ではありません。&lt;br&gt;
組み込みインデックスは、クエリのフィルタ（条件）や単純なソートで必要です。このためアプリケーションで、該当するプロパティがクエリのフィルタやソートに使用していないか確認する必要があります。もしインデックスが無いのにアプリケーションで使用すると、次のようなエラーがログに記録されます。

&lt;div class=&quot;highligh&quot; style=&quot;background: #ffffff; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #ffffff;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #888888&quot;&gt;BadFilterError: invalid filter: Cannot query for unindexed property xxxxxxx.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
複合インデックスの場合、index.yamlをデプロイすれば自動にインデックスを再構築します。しかし組み込みインデックスの場合、indexed=False と変更しデプロイしても、インデックスが削除される訳では無いようです。&lt;br&gt;
組み込みインデックスを削除するには、モデルの既存のエンティティ全ての更新処理が必要です。&lt;br&gt;
このため、インデックス削除による保存データ課金額のコスト削減効果と、全エンティティの更新処理でのコスト（インスタンス・エンティティ読み込み・エンティティ書き込みの各課金額）を比較し吟味する必要があります。

&lt;p&gt;
最初にサンプルとして示したエンティティですが、組み込みインデックスが不必要なプロパティに indexed=False  と設定し、更に全エンティティの更新処理をした結果、次のように変化しました。

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vQV6dlib4ahyphenhyphenh3vqjq-3DOAyAwE9X-8-yfn5sBfdDybtFl3n-CnKdhnxkTaQA_3z1Ybpp2dPPhS1Ot91U32RM0avwjqUx_i9RY1OuRyc-hP28B2CWR5LsI_wm5GuH386W94H1IawBUs/s1600/%25E3%2583%2586%25E3%2582%2599%25E3%2583%25BC%25E3%2582%25BF%25E3%2582%25B9%25E3%2583%2588%25E3%2582%25A2_%25E3%2582%25BF%25E3%2582%2599%25E3%2583%2583%25E3%2582%25B7%25E3%2583%25A5%25E3%2583%259B%25E3%2582%2599%25E3%2583%25BC%25E3%2583%2588%25E3%2582%2599_-_hima-click.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vQV6dlib4ahyphenhyphenh3vqjq-3DOAyAwE9X-8-yfn5sBfdDybtFl3n-CnKdhnxkTaQA_3z1Ybpp2dPPhS1Ot91U32RM0avwjqUx_i9RY1OuRyc-hP28B2CWR5LsI_wm5GuH386W94H1IawBUs/s640/%25E3%2583%2586%25E3%2582%2599%25E3%2583%25BC%25E3%2582%25BF%25E3%2582%25B9%25E3%2583%2588%25E3%2582%25A2_%25E3%2582%25BF%25E3%2582%2599%25E3%2583%2583%25E3%2582%25B7%25E3%2583%25A5%25E3%2583%259B%25E3%2582%2599%25E3%2583%25BC%25E3%2583%2588%25E3%2582%2599_-_hima-click.jpg&quot; width=&quot;640&quot; height=&quot;393&quot; data-original-width=&quot;1181&quot; data-original-height=&quot;725&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
１・２・４番目のプロパティの組み込みインデックスがゼロになっています。３番めのプロパティは検索条件に使用しているため、indexed=True になりインデックスはそのままです。これでも保存データは６割削減されました。

&lt;h5&gt;複合インデックスも整理&lt;/h5&gt;

&lt;p&gt;
複合インデックスでも、不要なインデックスをチェックしましょう。&lt;br&gt;
index.yaml の記述を見て、使用していないインデックスを記述から除外します。その後、index.yaml をデプロイします。&lt;br&gt;
&lt;strong&gt;appcfg&lt;/strong&gt;コマンドの時代は、アプリをデプロイすると自動的に index.yaml も更新されましたが、&lt;strong&gt;gcloud&lt;/strong&gt;では自動更新されません。次のように index.yaml をデプロイするためのコマンドを発行する必要があります。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;gcloud app deploy index.yaml&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
その後、index.yaml から除外されたインデックスをアプリからクリーンアップする必要があります。コマンドは次の通りです。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;gcloud datastore cleanup-indexes index.yaml&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
以上です。今回は Datasoreのデータ使用量削減という観点から、記事を書いてみました。


&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/4250367828564258313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/4250367828564258313'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2017/11/datastore.html' title='Datastore と組み込みインデックス'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRwOfgE07ZvxhpvxGO7eYbjO1gGMu02sv6Ck8EL6nsSmJxErERSMJ49xJSSCEzS8rjv6p2dAZKGIG7xEEI5FXOSQbcUXbdhJf-IxD5QZleEkhuyEtN1mPjbc5nCiJ9sLqprGzLK1WAJto/s72-c/%25E3%2583%2586%25E3%2582%2599%25E3%2583%25BC%25E3%2582%25BF%25E3%2582%25B9%25E3%2583%2588%25E3%2582%25A2_%25E3%2582%25BF%25E3%2582%2599%25E3%2583%2583%25E3%2582%25B7%25E3%2583%25A5%25E3%2583%259B%25E3%2582%2599%25E3%2583%25BC%25E3%2583%2588%25E3%2582%2599_-_hima-click.jpg" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-508423536674830471</id><published>2017-07-16T23:37:00.000+09:00</published><updated>2017-07-17T23:53:06.483+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>Python3 と web2py 、SQLEDITABLE</title><content type='html'>ちょっと前に、web2py &lt;strong&gt;2.15.1&lt;/strong&gt; が公開されましたが、このバージョンからは試験的に Python3 に対応しています。

&lt;p&gt;
&lt;a href=&quot;http://www.web2py.com/init/default/download&quot;&gt;web2py Download&lt;/a&gt;

&lt;p&gt;
また、これに合わせて、SQLEDITABLE もPython3に対応しました。

&lt;p&gt;
&lt;a href=&quot;https://github.com/hiho-/SQLEDITABLE/releases/tag/v0.30&quot;&gt;SQLEDITABLE version 0.30&lt;/a&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/508423536674830471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/508423536674830471'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2017/07/python3-web2py-sqleditable.html' title='Python3 と web2py 、SQLEDITABLE'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-4666097307057600552</id><published>2017-07-12T15:36:00.000+09:00</published><updated>2017-07-16T23:23:16.689+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Python3移行の注意点　ZIP・MAP組み込み関数</title><content type='html'>Python2のサポートは２０２０年までだそうです。Python3に関しては私は殆ど使用してこなかったのですが、最近環境も揃ってきたような気もします。このタイミングで、プラグイン・ライブラリのPython3への移行作業してみました。

&lt;p&gt;
作業自体は一日程度で終わりました。また移行したライブラリのPython2.7での動作は何も問題が無く、後方互換性もバッチリで感心しました。

&lt;p&gt;
今回はPython3向け修正作業で感じた、ZIP・MAP組み込み関数の注意点について記事にします。

&lt;h5&gt;ZIP関数、Python2での動作&lt;/h5&gt;

まずPython2での動作を見てみます。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 4, 7), (2, 5, 8), (3, 6, 9)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

３つのリストを一つのリストに変換しています。

&lt;p&gt;
また、For文やリスト内包表記を使ってみます。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1 4 7&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2 5 8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3 6 9&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 11), (2, 13), (3, 15)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

とくに問題なく、動作します。


&lt;h5&gt;ZIP関数、Python3での動作&lt;/h5&gt;

同様にZIP関数をPython3で動作させてみます。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;zip object at 0x10d6968c8&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

なんと、zipオブジェクトが返ってきました。

&lt;p&gt;
For文やリスト内包表記を試してみます。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1 4 7&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2 5 8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3 6 9&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
For文は実行できましたが、リスト内包表記は空のリストが返ってきただけでした。

&lt;p&gt;
zipオブジェクトというのは、ジェネレータと同様の遅延評価の機能を持っているそうですが、複数回の利用はできないみたいです。



&lt;h5&gt;ZIP関数をPython2と同様の動作に記述するには&lt;/h5&gt;

Python3で動作させるには、工夫が必要です。３つ案があります。

&lt;p&gt;
&lt;strong&gt;【案１】同じ記述を２つする&lt;/strong&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1 4 7&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2 5 8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3 6 9&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 11), (2, 13), (3, 15)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

zipオブジェクトは遅延評価なので、２つ記述してもオーバヘッドは無いようです。

&lt;br&gt;
&lt;p&gt;
&lt;strong&gt;【案２】リストやタプルに変換する&lt;/strong&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1 4 7&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2 5 8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3 6 9&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 11), (2, 13), (3, 15)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;br&gt;
&lt;p&gt;
&lt;strong&gt;【案３】itertools.teeを使用&lt;/strong&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;itertools&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itertools&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1 4 7&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2 5 8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3 6 9&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 11), (2, 13), (3, 15)]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

itertools.teeで、一つのイテレータからN個の独立したイテレータを返すことができます。&lt;br&gt;
参考： &lt;a href=&quot;https://docs.python.jp/3/library/itertools.html#itertools.tee&quot;&gt;itertools.tee(iterable, n=2)&lt;/a&gt;

&lt;p&gt;
他にもあるかもしれませんが、取り敢えず、これだけ挙げてみました。


&lt;h5&gt;MAP関数、Python3での動作&lt;/h5&gt;

&lt;p&gt;
Python3では、MAP関数もZIPと同様の動作になります。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;map object at 0x10d69a2e8&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(1, 11)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(2, 13)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(3, 15)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;br&gt;
&lt;p&gt;
また、Python2 では最初の引数に None を指定すると、最大の配列数に長さを合わせて結合してくれました。しかし、Python3では使用するとエラーになります。

&lt;p&gt;
Python2
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 4, 7), (2, 5, None), (3, None, None)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Python3
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;#x27;NoneType&amp;#x27; object is not callable&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h5&gt;MAP関数をPython2と同様の動作に記述するには&lt;/h5&gt;

&lt;p&gt;
MAP関数も、ZIP同様の解決策を適用可能です。

&lt;p&gt;
&lt;strong&gt;【案１】同じ記述を２つする&lt;/strong&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(1, 11)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(2, 13)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(3, 15)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 11), (2, 13), (3, 15)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;br&gt;
&lt;p&gt;
&lt;strong&gt;【案２】リストやタプルに変換する&lt;/strong&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(1, 11)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(2, 13)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(3, 15)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 11), (2, 13), (3, 15)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;br&gt;
&lt;p&gt;
&lt;strong&gt;【案３】itertools.teeを使用&lt;/strong&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;itertools&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itertools&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;go&quot;&gt;(1, 11)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(2, 13)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(3, 15)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 11), (2, 13), (3, 15)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

参考： &lt;a href=&quot;https://docs.python.jp/3/library/itertools.html#itertools.tee&quot;&gt;itertools.tee(iterable, n=2)&lt;/a&gt;

&lt;br&gt;&lt;br&gt;
&lt;p&gt;
&lt;strong&gt;【案４】 itertools.zip_longestを使用&lt;/strong&gt;&lt;br&gt;
Python2の map(None, [1,2,3], [4,5], [7]) と同じ動作をさせる方法ですが、 itertools.zip_longest を使うと良いそうです。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;itertools&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;itertools&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zip_longest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 4, 7), (2, 5, None), (3, None, None)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

itertools.zip_longest も、ZIP関数同様の遅延評価のイテレータです。

&lt;br&gt;
参考：&lt;a href=&quot;https://docs.python.jp/3/library/itertools.html#itertools.zip_longest&quot;&gt;itertools.zip_longest&lt;/a&gt;


&lt;h5&gt;最後に&lt;/h5&gt;

ZIPやMAP関数の動作の違いは、Python2のコードをPython3で動かしたらエラーになる訳ではないので、発覚しにくいです。仕様の違いを知らないと悩むことになるので、気を付けたいですよね。

&lt;p&gt;
参考&lt;br&gt;
&lt;a href=&quot;https://stackoverflow.com/questions/25040456/cannot-unpack-a-zip-object-multiple-times&quot;&gt;Cannot unpack a zip object multiple times&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://stackoverflow.com/questions/12015521/python-3-vs-python-2-map-behavior&quot;&gt; Python 3 vs Python 2 map behavior&lt;/a&gt;







&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/4666097307057600552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/4666097307057600552'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2017/07/python3-zipmap.html' title='Python3移行の注意点　ZIP・MAP組み込み関数'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-7707789441497641555</id><published>2017-07-09T18:54:00.003+09:00</published><updated>2023-01-06T23:26:29.315+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Golang"/><category scheme="http://www.blogger.com/atom/ns#" term="Google AppEngine"/><title type='text'>GAE環境下でのペンドリングとデプロイ</title><content type='html'>前回記事（&lt;a href=&quot;http://todayspython.blogspot.com/2017/07/gae-echo.html&quot;&gt;GAE環境下での Echoフレームワークのエラー&lt;/a&gt;）で、EchoフレームワークはGAE（GoogleAppEngine）環境下ではバージョン指定をするという話を書きました。今回は続編で、Go言語の機能であるベンドリング（vendoring）を利用し、もっと簡単にパッケージ管理を行います。さらにベンドリング使用時、GAEデプロイに関する注意点も書いていきます。

&lt;h5&gt;ベンドリングと Glide&lt;/h5&gt;

ペンドリング（Vendoring）は、プロジェクト毎の外部ライブラリを管理する仕組みです。Go言語バージョン1.5から利用可能になりました。

&lt;p&gt;
簡単に解説すると、プロジェクトのディレクトリに &lt;strong&gt;vendor&lt;/strong&gt;というディレクトリを作成し、vendor下にプロジェクトで使用する外部ライブラリーを配置します。これにより利用するライブラリを、プロジェクト毎に管理することができます。

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1gxYdEfcKSkDfQMMt6Pa_X6hj2imrCBFP3y3GtXdTln50gCne1VPiLB2xJrQXRhrQ0K8sS0-z_eXgewOrAo8dw52XkMbnawWzSOYSa0zifqEl02PRl1QD0nePZYJPuRBpqn4V6BfnmzY/s1600/Macintosh_SSD.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1.5em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1gxYdEfcKSkDfQMMt6Pa_X6hj2imrCBFP3y3GtXdTln50gCne1VPiLB2xJrQXRhrQ0K8sS0-z_eXgewOrAo8dw52XkMbnawWzSOYSa0zifqEl02PRl1QD0nePZYJPuRBpqn4V6BfnmzY/s1600/Macintosh_SSD.png&quot; data-original-width=&quot;407&quot; data-original-height=&quot;287&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;br clear=&quot;all&quot;&gt;

このペンンドリングを簡単に管理できる、パッケージ管理ツールが幾つかあります。有名なツールを挙げます（☆はgithubの星の数）。

&lt;ul style=&quot;margin:1em;&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tools/godep&quot;&gt;Godep&lt;/a&gt; ☆４７４０&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/constabulary/gb&quot;&gt;GB&lt;/a&gt; ☆１９５７&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Masterminds/glide&quot;&gt;Glide&lt;/a&gt; ☆４８８１&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kardianos/govendor&quot;&gt;Govendor&lt;/a&gt; ☆２１３２&lt;/li&gt;
&lt;/ul&gt;

最も有名なのは Godep のようです、Go言語がベンドリングに対応する前からあるそうです。古いので環境を汚したりとか、最近あまり更新されない等あるそうです。そして最も人気なのは、&lt;strong&gt;Glide&lt;/strong&gt; です。機能範囲も最も大きいいようです。今回は Glide を使用します。

&lt;br&gt;
参考：&lt;a href=&quot;https://github.com/Masterminds/glide/wiki/Go-Package-Manager-Comparison&quot;&gt;Go Package Manager Comparison&lt;/a&gt;

&lt;p&gt;
Glideの使用方法は、いろいろなところで解説されています。詳しい解説は、そちらを参考にしてください。

&lt;p&gt;
参考&lt;br&gt;
&lt;a href=&quot;http://nasust.hatenablog.com/entry/glide&quot;&gt;Go言語 / golang 入門 必見!! パッケージ管理ツール Glideの使用方法を詳しく解説&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://liginc.co.jp/305623&quot;&gt;【GO言語のパッケージ管理：決定版】「Glide」を使ってみよう&lt;/a&gt;

&lt;p&gt;
まず Glideをインストールします。マシンはMacですので、brew でインストールします。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ brew install glide
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
次にGlideの設定ファイル（glide.yaml）を作成するため、プロジェクトのディレクトリで次のコマンドを実行します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ glide create
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
実行すると、いろいろ設定ウィザードが表示されます。取り敢えず最初のウィザードで No（N） を選ぶと、プロジェクトを検索し依存関係を記述した glide.yaml を生成します。
生成した glide.yaml は、次のようになります。

&lt;div class=&quot;highligh&quot; style=&quot;background: #ffffff; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #ffffff;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span&gt;&lt;/span&gt;package: sample
import:
- package: github.com/labstack/echo
  subpackages:
  - middleware
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
ここで、依存するパッケージは github.com/labstack/echo　なのを確認します。またバージョンを 3.0.2 に指定する必要があるので、次のようにversionを記述します。 

&lt;div class=&quot;highligh&quot; style=&quot;background: #ffffff; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #ffffff;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span&gt;&lt;/span&gt;package: sample
import:
&lt;span style=&quot;background-color: #ffffcc&quot;&gt;- package: github.com/labstack/echo
&lt;/span&gt;&lt;span style=&quot;background-color: #ffffcc&quot;&gt;  version: 3.0.2
&lt;/span&gt;  subpackages:
  - middleware
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;
vendorディレクトリを作成し、依存するライブラリをインストールします。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ glide install
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
ライブラリはインストールされましたが、指定したバージョンはまだインストールされていません。ここでライブラリのアップデートを行います。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ glide up
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
これによって、バージョン3.0.2が設定されました。



&lt;h5&gt;ペンドリング使用時のプロジェクトの位置&lt;/h5&gt;

GAEのベンドリング使用時、プロジェクトのディレクトリは &lt;strong&gt;GOPATH&lt;/strong&gt; 配下に設置する必要があります。GOPATH下でない場合、vendorディレクトリが GAEのSDKで認識されないようです。

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgELwzg7SzppV2j-OlZppd0B8AksRU0sItl31mU0tnBRRSgLo8WytgIog4OBu5FCL0T2vo43MoVCq3s4Rbw2MSDZTVPp5BBV-jt8rquB4vHoZcarikgv2BowpjvwMtxLoOSqhqwcOCr-bg/s1600/Macintosh_SSD.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgELwzg7SzppV2j-OlZppd0B8AksRU0sItl31mU0tnBRRSgLo8WytgIog4OBu5FCL0T2vo43MoVCq3s4Rbw2MSDZTVPp5BBV-jt8rquB4vHoZcarikgv2BowpjvwMtxLoOSqhqwcOCr-bg/s1600/Macintosh_SSD.png&quot; data-original-width=&quot;433&quot; data-original-height=&quot;381&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;
※ プロジェクト下のファイルは、EchoフレームワークのGAEレシピで紹介されたサンプルです（&lt;a href=&quot;https://echo.labstack.com/cookbook/google-app-engine&quot;&gt;Google App Engine Recipe&lt;/a&gt;）。

&lt;br clear=&quot;all&quot;&gt;

プロジェクトのディレクトリでターミナルを開いて、ローカル開発用サーバを起動してみましょう。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; dev_appserver.py app.yaml
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
エラー無く、稼働できることを確認できると思います（EchoフレームワークのGAEレシピのサンプルデータ一覧URLは、http://localhost:8080/users になります）。


&lt;h5&gt;GAEへのデプロイ&lt;/h5&gt;

GCLOUDコマンド（参考：&lt;a href=&quot;http://todayspython.blogspot.com/2016/12/google-cloud-sdk.html&quot;&gt;Google Cloud SDK への移行&lt;/a&gt;）で、ベンドリングしたアプリをGAEにデプロイしようとするとエラーで処理が止まります。具体的には次のようなエラーが表示されます。

&lt;div class=&quot;highligh&quot; style=&quot;background: #eeeedd; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #eeeedd;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #555555&quot;&gt;$&lt;/span&gt; gcloud app deploy app.yaml --version 1
&lt;span style=&quot;color: #888888&quot;&gt;Services to deploy:&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;:::: 省略 :::::&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;Updating service [default]...failed.                                                                                             &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed:&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;2017/07/08 18:00:00 go-app-builder: Failed parsing input: parser: bad import &amp;quot;syscall&amp;quot; in vendor/golang.org/x/sys/plan9/env_unset.go&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
このエラーに関しては、GAEの設定ファイル（app.yaml） に次のようにデプロイしないライブラリを指定すると良いそうです。

&lt;div class=&quot;highligh&quot; style=&quot;background: #ffffff; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #ffffff;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span&gt;&lt;/span&gt;nobuild_files:
- vendor
&lt;/pre&gt;&lt;/div&gt;

参考：&lt;a href=&quot;http://tweeeety.hateblo.jp/entry/2017/01/16/233249&quot;&gt;golang環境でFailed parsing input: parser: bad import &quot;syscall&quot; というエラーが出るときのメモ&lt;/a&gt;

&lt;p&gt;
しかし再度コマンドを発行すると、同様のエラーが出てデプロイが失敗します。

&lt;p&gt;
現状ではGCLOUDコマンドは、上手くベンドリングに対応していないようです。このため一つ前のツールである、&lt;strong&gt;GOAPP&lt;/strong&gt;を使用します。GOAPPは brew でもインストール可能なようです。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; brew install goapp
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
ダンロードで goappツールを導入する場合は、&lt;a href=&quot;https://cloud.google.com/appengine/docs/standard/go/download#go_mac&quot;&gt;GAE SDK ダンロードページ&lt;/a&gt;の &lt;strong&gt;Or, you can download the original App Engine SDK for Go.&lt;/strong&gt; から行います。

&lt;p&gt;
そしてデプロイします。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; goapp deploy -application sample -version &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; app.yaml
&lt;/pre&gt;&lt;/div&gt;

デプロイが成功しました。

&lt;p&gt;
※ GAEの設定ファイル（app.yaml） の nobuild_files が無い場合、goappでも同様のエラーが出ますので、記述する必要があります。


&lt;h5&gt;最後に&lt;/h5&gt;

GOPATH下にプロジェクト・ディレクトを設置する場合、シンボリックリンクを検討することもあるかと思います。シンボリックリンクでの設置では、デプロイは可能ですが、なぜか開発用サーバはエラーが出て起動できません。この辺、注意してください。

&lt;p&gt;
GAE SDK for Go は、Goの機能に追いついていない所や動作がおかしな点があるのかもしれません。一応、現状でまとめてみました。

&lt;p&gt;
&lt;br&gt;
&lt;p&gt;

※追記（2017/07/28）
&lt;br&gt;
６月末にリリースされた SDK 1.9.55 以降、Go1.8をベータサポートしているそうです。このため、app.yaml の api_versionを次のように指定すると、ベンドリングを使用しなくても Echoフレームワークが動作します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;api_version&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;go1.8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

ただし、ローカル開発用サーバでは現在動作しません。またデプロイには、GCLOUDコマンドではなく、GOAPPコマンドを利用する必要があります。











&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/7707789441497641555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/7707789441497641555'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2017/07/gae.html' title='GAE環境下でのペンドリングとデプロイ'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1gxYdEfcKSkDfQMMt6Pa_X6hj2imrCBFP3y3GtXdTln50gCne1VPiLB2xJrQXRhrQ0K8sS0-z_eXgewOrAo8dw52XkMbnawWzSOYSa0zifqEl02PRl1QD0nePZYJPuRBpqn4V6BfnmzY/s72-c/Macintosh_SSD.png" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-8941108567819008040</id><published>2017-07-01T01:36:00.001+09:00</published><updated>2023-01-06T23:28:05.028+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Golang"/><category scheme="http://www.blogger.com/atom/ns#" term="Google AppEngine"/><title type='text'>GAE環境下での Echoフレームワークのエラー</title><content type='html'>Echoフレームワークは、最近注目されている Go言語の高パフォーマンス・フレームワークです。シンプルかつ、意外とドキュメントも整備されており、メンテナンスも頻繁に行われているようです。

&lt;p&gt;
参考: &lt;a href=&quot;https://echo.labstack.com/&quot;&gt;https://echo.labstack.com/&lt;/a&gt;

&lt;p&gt;
GAE（Google App Engine）環境下で動作させるマニュアル（gcloudコマンド用では無いですが・・・）も整備されています。しかしサンプルを実際に動かしてみると、エラーで動作しません。初めは何だか良くわからなかったのですが、時間が掛かりましたが原因がわかり動作可能になりました。この件を記事にしてみます。

&lt;div style=&quot;border: 1px dashed orange;padding:10px&quot;&gt;
　&lt;a href=&quot;http://todayspython.blogspot.com/2017/07/gae.html&quot;&gt;GAE環境下でのペンドリングとデプロイ&lt;/a&gt; ← こちらも参照ください（違う方法で解決）
&lt;/div&gt;



&lt;h5&gt;Echoのエラー&lt;/h5&gt;

ローカル環境で、GAEテストサーバを動作させると、エラー次のエラーが表示されます。

&lt;p&gt;
テストサーバ実行コマンド（gcloudコマンド）&lt;br&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ dev_appserver.py app.yaml
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
表示されるエラー&lt;br&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;INFO     2017-06-30 18:16:29,531 admin_server.py:116&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Starting admin server at: http://localhost:8000
ERROR    2017-06-30 18:16:31,076 go_runtime.py:184&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Failed to build Go application: 
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Executed command: /Users/xxx/google-cloud-sdk/platform/google_appengine/goroot-1.6/bin/go-app-builder -app_base ...省略... &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
/Users/xxx/go/src/golang.org/x/crypto/acme/acme.go:18: can&lt;span class=&quot;s1&quot;&gt;&amp;#x27;t find import: &amp;quot;context&amp;quot;&lt;/span&gt;

&lt;span class=&quot;s1&quot;&gt;2017/06/30 18:16:31 Can&amp;#x27;&lt;/span&gt;t find package &lt;span class=&quot;s2&quot;&gt;&amp;quot;context&amp;quot;&lt;/span&gt; in &lt;span class=&quot;nv&quot;&gt;$GOPATH&lt;/span&gt;: cannot find package &lt;span class=&quot;s2&quot;&gt;&amp;quot;context&amp;quot;&lt;/span&gt; in any of:
 /Users/xxx/google-cloud-sdk/platform/google_appengine/goroot-1.6/src/context &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;from &lt;span class=&quot;nv&quot;&gt;$GOROOT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 /Users/xxx/go/src/context &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;from &lt;span class=&quot;nv&quot;&gt;$GOPATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
2017/06/30 18:16:31 go-app-builder: build timing: 0×skip &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2ms total&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 5×compile &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;258ms total&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 0×link &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; total&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
2017/06/30 18:16:31 go-app-builder: failed running compile: &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; status 2
&lt;/pre&gt;&lt;/div&gt;

&lt;h5&gt;エラー原因&lt;/h5&gt;

エラーの原因はズバリ、Echo側にあります。GAEのSDKには、Go言語が内包されています。しかしこのGo言語は、バージョン1.6系なのです。しかし Echoの最新版では、バージョン1.6系のサポートが外れました。このため、エラーが出て動作しないようです。

&lt;p&gt;
Echoのサポートが外れたのは、バージョン3.20 からです。しかしその前のバージョンも、GAEに関しては問題が発生して動作しません。結局、バージョン3.02まで遡らないと動作はしないようです。

&lt;p&gt;
参考&lt;br&gt;
&lt;a href=&quot;https://ja.stackoverflow.com/questions/34606/gae%E3%82%92echo%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%9D%E3%81%86%E3%81%A8%E3%81%99%E3%82%8B%E3%81%A8&quot;&gt;gaeをechoで動かそうとすると&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://github.com/labstack/echo/releases&quot;&gt;https://github.com/labstack/echo/releases&lt;/a&gt;



&lt;h5&gt;エラー対策&lt;/h5&gt;

&lt;p&gt;
まずEchoのインストールを行います。
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ go get -u github.com/labstack/echo/...
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Echo のインストール・ディレクトリ（例 /Users/xxx/go/src/github.com/labstack/echo 等）に移動し、タグ一覧を参照します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ git tag -l
2.0.0-alpha
v0.0.10
...省略...
v3.0.1
v3.0.2
v3.0.3
v3.1.0
v3.1.0-rc.1
v3.2.0
v3.2.1
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
3.0.2にチェックアウトします。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ git checkout -b 3.0.2 refs/tags/v3.0.2
Switched to a new branch &lt;span class=&quot;s1&quot;&gt;&amp;#x27;3.0.2&amp;#x27;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
ブランチ一覧を表示してみます。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ git branch
* 3.0.2
  master
&lt;/pre&gt;&lt;/div&gt;

3.0.2 にブランチが移動したことが確認できます。

&lt;p&gt;
プロジェクトのディレクトリに戻り、GAEテストサーバが動作するか確認します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ dev_appserver.py app.yaml
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
参考： &lt;a href=&quot;http://d.hatena.ne.jp/kanonji/20110304/1299211488&quot;&gt;gitでタグをチェックアウトする。&lt;/a&gt;



&lt;h5&gt;ブランチした Echo を最新版に更新する&lt;/h5&gt;

ブランチした Echo を元に戻し、最新版に更新するには次のようにします。

&lt;p&gt;
master にチェックアウトします。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ git checkout master
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
作成した 3.0.2 ブランチを削除します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ git branch -d 3.0.2
Deleted branch 3.0.2 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;was cd2530e&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
オプション &lt;strong&gt;u&lt;/strong&gt; を付けて再度、git getコマンドを実行します。 

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;go get -u github.com/labstack/echo/...
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
参考： &lt;a href=&quot;https://stackoverflow.com/questions/30188499/how-to-do-go-get-on-a-specific-tag-of-a-github-repository&quot;&gt;How to do “go get” on a specific tag of a github repository&lt;/a&gt;&lt;br&gt;



&lt;h5&gt;最後に&lt;/h5&gt;

以上で当面、EchoをGAEで使用できるようになりました。しかし依存ライブラリの管理を行う、Godep等のツールを導入し、プロジェクト毎にパッケージを管理した方が理に適っていると思います。この辺は色々難しそうなので、もう少し調べて記事にしたいと考えています。

&lt;p&gt;
参考： &lt;a href=&quot;https://stackoverflow.com/questions/33018414/how-to-checkout-a-release-with-go-get&quot;&gt;How to checkout a release with go get?&lt;/a&gt;



&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8941108567819008040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8941108567819008040'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2017/07/gae-echo.html' title='GAE環境下での Echoフレームワークのエラー'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-2766106809631019173</id><published>2017-06-30T19:30:00.000+09:00</published><updated>2017-06-30T21:36:03.499+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Golang"/><title type='text'>goenv導入</title><content type='html'>GO言語のバージョンを気軽に変更できるツール &lt;strong&gt;goenv&lt;/strong&gt; を導入のメモ

&lt;h5&gt;goenvについて&lt;/h5&gt;

goenvは、pyenvやrbenvと同様のツールです。コマンドも大抵の場合、pyenvなどと合わせてあり理解しやすいです。
しかし、goenvは同名のツールが乱立しており、調べたら沢山あって驚きました。

&lt;p&gt;
※GODOCに載っていた同名ツール
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tmilewski/goenv&quot;&gt;https://github.com/tmilewski/goenv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/adjust/goenv&quot;&gt;https://github.com/adjust/goenv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bitbucket.org/ymotongpoo/goenv&quot;&gt;https://bitbucket.org/ymotongpoo/goenv&lt;/a&gt; → 日本人が開発者のようです（結構独特かも）&lt;/li&gt;
&lt;/ul&gt;

※その他
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/syndbg/goenv&quot;&gt;https://github.com/syndbg/goenv&lt;/a&gt; → brewで導入できる goenv&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pwoolcoc/goenv&quot;&gt;https://github.com/pwoolcoc/goenv&lt;/a&gt; → python製 goenv&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/crsmithdev/goenv&quot;&gt;https://github.com/crsmithdev/goenv&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
この他、rbvm と同様のツールである &lt;strong&gt;gvm&lt;/strong&gt; もあります。
&lt;p&gt;
&lt;a href=&quot;https://github.com/moovweb/gvm&quot;&gt;https://github.com/moovweb/gvm&lt;/a&gt;
&lt;p&gt;
こちらの方が、メジャーなようです。

&lt;p&gt;
私は滅多に使わないので、pyenvとコマンドが一緒で、brewで簡単に導入できる、https://github.com/syndbg/goenv を使用します。


&lt;h5&gt;goenvのインストール&lt;/h5&gt;

macOSの場合は、brewでインストール可能です。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ brew update
$ brew install goenv
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt; 

&lt;p&gt;
次に、bashプロファイル（.bash_profile）に、次に一行を追加します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;goenv init -&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
以上でインストールを完了です。変更したbashプロファイルをターミナルで再読込する場合は、次のコマンドを実行します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ &lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; ~/.bash_profile
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
※ Windowsの場合は、こちらを参照してください。&lt;br&gt;
&lt;a href=&quot;https://github.com/syndbg/goenv&quot;&gt;https://github.com/syndbg/goenv&lt;/a&gt;



&lt;h5&gt;goenv使い方&lt;/h5&gt;

pyenvと同じだと思いますが、使い方を書いてみます。

&lt;p&gt;
goenvでインストール可能なgoのバーション一覧は、次のコマンドで表示できます。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ goenv install -l
Available versions:
  1.2.2
  1.3.0
  1.3.1
  ...省略...
  1.7.5
  1.8.0
  1.8.1
  1.8.3
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
試しに、1.6.3を導入してみます。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ goenv install 1.6.3
Downloading go1.6.3.darwin-amd64.tar.gz...
-&amp;gt; https://storage.googleapis.com/golang/go1.6.3.darwin-amd64.tar.gz
Installing Go Darwin 64bit 1.6.3...
Installed Go Darwin 64bit 1.6.3 to /Users/xxx/.goenv/versions/1.6.3
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
1.6.3に切り替えるには、次のコマンドでグローバル設定を変えれます。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ goenv global 1.6.3
&lt;/pre&gt;&lt;/div&gt;

しかしデフォルト設定してしまうと、goenvコマンドでは元に戻すことができません。

&lt;p&gt;
ローカルのディレクトリーのみ設定を変える場合は、

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ goenv &lt;span class=&quot;nb&quot;&gt;local&lt;/span&gt; 1.6.3
&lt;/pre&gt;&lt;/div&gt;

とします。
&lt;p&gt;
ローカル設定では、--unset オプションで元に戻すことが可能です。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ goenv &lt;span class=&quot;nb&quot;&gt;local&lt;/span&gt; --unset
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
さてgoのバージョンを確認してみましょう。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ go version
go version go1.6.3 darwin/amd64
&lt;/pre&gt;&lt;/div&gt;

1.6.3に切り替わったことが確認できると思います。

&lt;p&gt;
最新バージョンもインストールして切り替えれるようにした方が良いでしょう。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ goenv install 1.8.3
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
goenvでインストール済みバージョンと、現在使用中のバージョンを表示するには次のコマンドです。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;$ goenv versions
  system
* 1.6.3 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; by /Users/xxx/.goenv/version&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  1.8.3
&lt;/pre&gt;&lt;/div&gt;

system と表示されているのは、goenv外（brew）でインストールした go言語です。

&lt;p&gt;
グローバル設定の取り消しコマンドはありませんが、バージョン表示されている /Userx/xxx/.goenv/version ファイルを削除すれば、設定を取り消すことが可能です。

&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/2766106809631019173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/2766106809631019173'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2017/06/goenv.html' title='goenv導入'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-5665802298252747619</id><published>2017-06-30T19:28:00.000+09:00</published><updated>2017-06-30T19:28:57.141+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Golang"/><title type='text'>Go言語</title><content type='html'>最近、Go言語（&lt;strong&gt;Golang&lt;/strong&gt;）にも手を染めています。メモしておかないと忘れそうな事も多いので、このブログでもGoの記事を公開することにします。&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/5665802298252747619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/5665802298252747619'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2017/06/go.html' title='Go言語'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-3046637934638249205</id><published>2016-12-09T00:05:00.000+09:00</published><updated>2017-06-10T20:16:17.127+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google AppEngine"/><title type='text'>Google Cloud SDK への移行</title><content type='html'>Google App Engine（GAE）を利用していますが、いつの間にかSDKやツール・コマンドなどが変更になりました。従来の &lt;strong&gt;APPCFG&lt;/strong&gt;とは全く違うので、最低限の使い方をメモ書きレベルで記事にします。

&lt;h5&gt;GCLOUD&lt;/h5&gt;

結構前から、Google Cloud Platform の管理コマンドをまとめたツールが &lt;strong&gt;GCLOUD&lt;/strong&gt; として配布されいます。最近まで、GUIツールも含んだ従来のGAEの管理ツール（APPCFG）も配布されていましたが、現在従来型ツールは非公開になっています。

&lt;p&gt;
参考: &lt;a href=&quot;https://cloud.google.com/sdk/&quot; target=&quot;_blank&quot;&gt;CLOUD SDK&lt;/a&gt;

&lt;p&gt;
GCLOUD は、GUIツールは無く、全てコマンドラインから操作します。その代わり従来ツールでは不可能だった、Google Cloud Platform に関する細かな管理が可能です。

&lt;h5&gt;Google Cloud SDK インストール&lt;/h5&gt;

まず上記のリンクから、Google Cloud SDK をダウンロード・インストールします。ちなみに私の場合、Windwos10ではインストールが成功しましたが、MacOSでは何度試行してもインストールできませんでした。OSが二世代前の Yosemite、というのも理由かもしれません。

&lt;p&gt;
開発環境は MacOS の方が良いと最近言われていますが、今回、Windows10の良さを再認識できました。MacOSよりキビキビ動くし、遅ればせながら &lt;strong&gt;PowerShell&lt;/strong&gt; を利用したところ、コマンドライン環境で特に不便なことは無かったです

&lt;p&gt;
※ 今回の記事中のコマンド例は、PowerShellの環境です。


&lt;p&gt;
※ MacOSでもインストールできました、手順としては以下の通りです。（追記 1/18）

&lt;div style=&quot;margin-left:15px;&quot;&gt;
&lt;ol&gt;
&lt;li&gt;コンソールから次のコマンドでインストール&lt;br&gt;
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;curl https://sdk.cloud.google.com &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; bash
&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
インストールが成功したら、次のコマンドで初期設定を行う。
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;gcloud init
&lt;/pre&gt;&lt;/div&gt;
gcloudコマンドでのデフォルト・ユーザとデフォルト・アプリの設定を行います。
&lt;/li&gt;
&lt;li&gt;
この他に、
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;gcloud components list
&lt;/pre&gt;&lt;/div&gt;
コマンドでコンポーネントのリストを確認しようとすると、次のようなエラーが表示されることがあります。
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;ERROR: &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gcloud.components.list&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; Failed to fetch component listing from server.
&lt;/pre&gt;&lt;/div&gt;
この場合は、次のコマンドで修復ができるようです。
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;brew update
brew uninstall python
brew upgrade openssl
brew install python --with-brewed-openssl
&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
参考:&lt;br&gt;
&lt;a href=&quot;http://qiita.com/yuko/items/aaac6ea9536cd529106f&quot; target=&quot;_blank&quot;&gt;Google Compute Engine を使うための準備（Google Cloud SDK インストール - Linux &amp;amp;amp; OS X 編）&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://code.google.com/p/google-cloud-sdk/issues/detail?id=143&quot; target=&quot;_blank&quot;&gt;Failed to fetch component listing from server&lt;/a&gt;

&lt;/div&gt;

&lt;h5&gt;APPCFGからの移行&lt;/h5&gt;

&lt;p&gt;
従来のAPPCFGからGCLOUDに移行する場合に、まずアプリの幾つかの &lt;strong&gt;yaml&lt;/strong&gt; ファイルを書き換える必要があります。

&lt;p&gt;

&lt;ul&gt;
&lt;li&gt;アプリ定義（デフォルト・モジュール） - app.yaml&lt;br&gt;
プロジェクト名（&lt;strong&gt;application&lt;/strong&gt;）とバージョン（&lt;strong&gt;version&lt;/strong&gt;）の指定は、コメントにします。この記述があるとエラーで、アプリのデプロイができません。&lt;br&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;c&quot;&gt;#application: myapp&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#version: 1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;br&gt;&lt;/li&gt;
&lt;li&gt;モジュール定義 - （例）back_job.yaml&lt;br&gt;

プロジェクト名・バージョンをコメントアウトにするのに加えて、モジュール名の項目名を、module から &lt;strong&gt;service&lt;/strong&gt; に変更します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#application: myapp&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#module: back-job&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;back-job&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#version: 1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
プロジェクト名は、SDKインストール時に指定したデフォルトのプロジェクト名を使用します（変更方法は後述）。バージョンは、GCLOUD コマンドのデプロイ時に指定します。



&lt;h5&gt;デプロイ&lt;/h5&gt;

&lt;p&gt;
GCLOUDでのアプリケーションのデプロイは、コマンド環境から次のように指定します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deploy&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;yaml&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;-version&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;-no-promote&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
アプリのフォルダ上で実行しています。ここでは、二つオープションを指定します。

&lt;dl&gt;
&lt;dt&gt;--version（-v でも）&lt;/dt&gt;
&lt;dd&gt;デプロイするバージョンを指定します。例では、１を指定しています。&lt;/dd&gt;
&lt;dt&gt;--no-promote&lt;/dt&gt;
&lt;dd&gt;このオプションを付けないと、デプロイ後直ぐにトラフィックが１００％移行してしまいます。テスト＆確認後バージョンを移行する場合は、Cloud Platformのバージョン&lt;a href=&quot;https://console.cloud.google.com/appengine/versions&quot; target=&quot;_blank&quot;&gt;管理画面&lt;/a&gt;から、トラフィックを移行させます。&lt;/dd&gt;
&lt;/dl&gt;

&lt;br&gt;
&lt;div style=&quot;margin-left:30px;&quot;&gt;
実行例

&lt;div class=&quot;highligh&quot; style=&quot;background: #f0f3f3; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #f0f3f3;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000099; font-weight: bold&quot;&gt;PS C:\myapp\web2py&amp;gt; &lt;/span&gt;gcloud app deploy app.yaml --version 1 --no-promote
&lt;span style=&quot;color: #AAAAAA&quot;&gt;You are about to deploy the following services:&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt; - myapp/default/1 (from [C:\myapp\web2py\app.yaml])&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;     Deploying to URL: [https://1-dot-myapp.appspot.com]&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;     (add --promote if you also want to make this service available from&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;     [https://myapp.appspot.com])&lt;/span&gt;

&lt;span style=&quot;color: #AAAAAA&quot;&gt;Do you want to continue (Y/n)?  y&lt;/span&gt;

&lt;span style=&quot;color: #AAAAAA&quot;&gt;Beginning deployment of service [default]...&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;Some files were skipped. Pass `--verbosity=info` to see which ones.&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;You may also view the gcloud log file, found at&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;[C:\Users\xxx\AppData\Roaming\gcloud\logs\2016.12.08\12.03.23.383000.log].&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;File upload done.&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;Updating service [default]...done.&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;Deployed service [default] to [https://1-dot-myapp.appspot.com]&lt;/span&gt;

&lt;span style=&quot;color: #AAAAAA&quot;&gt;You can read logs from the command line by running:&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;  $ gcloud app logs read -s default&lt;/span&gt;

&lt;span style=&quot;color: #AAAAAA&quot;&gt;To view your application in the web browser run:&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;  $ gcloud app browse&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;
モジュールをデプロイする場合は、下のようにモジュールの yaml ファイルを指定します。下のコマンドでは、デフォルトモジュールと back-job モジュールの、二つがデプロイされます。 


&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deploy&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;yaml&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;back_job&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;yaml&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;-version&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;-no-promote&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;
cron.yaml や queue.yaml 、index.yaml などを変更した場合は、次のようにデプロイを指定します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deploy&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cron&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;yaml&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;yaml&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;br&gt;

&lt;div style=&quot;margin-left:30px;&quot;&gt;
実行例


&lt;div class=&quot;highligh&quot; style=&quot;background: #f0f3f3; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #f0f3f3;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000099; font-weight: bold&quot;&gt;PS C:\myapp\web2py&amp;gt; &lt;/span&gt;gcloud app deploy cron.yaml queue.yaml
&lt;span style=&quot;color: #AAAAAA&quot;&gt;You are about to deploy the following configurations:&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt; - myapp/cron  (from [C:\myapp\web2py\cron.yaml])&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt; - myapp/queue  (from [C:\myapp\web2py\queue.yaml])&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;Do you want to continue (Y/n)?  y&lt;/span&gt;

&lt;span style=&quot;color: #AAAAAA&quot;&gt;Updating config [cron]...done.&lt;/span&gt;
&lt;span style=&quot;color: #AAAAAA&quot;&gt;Updating config [queue]...done.&lt;/span&gt;

&lt;span style=&quot;color: #AAAAAA&quot;&gt;Cron jobs have been updated.&lt;/span&gt;

&lt;span style=&quot;color: #AAAAAA&quot;&gt;Task queues have been updated.&lt;/span&gt;

&lt;span style=&quot;color: #AAAAAA&quot;&gt;The Cloud Platform Console Task Queues page has a tab that shows the tasks that are running cron jobs.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;p&gt;
初めてデプロイするプロジェクトでは、ファイルロックのワーニングが表示される時があります。しかし何度がデプロイを実行すると、ワーニングが表示されなくなります。


&lt;h5&gt;ローカルのテスト環境&lt;/h5&gt;

&lt;p&gt;
従来、GUIツールから起動できたローカルのテスト環境は、GCLOUDコマンドからは起動できないようです。代わりに、dev_appserver.py を利用します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;PS C:\myapp\web2py&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dev_appserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

パラメータとして、app.yaml があるフォルダーを指定します。現在そのフォルダーで作業している場合は、ピリオド（.）を指定します。


&lt;p&gt;
すると、Pythonコンソールが起動します。

&lt;div class=&quot;highligh&quot; style=&quot;background: #202020; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #202020;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #cccccc&quot;&gt;INFO     2016-12-08 12:02:58,164 api_server.py:205] Starting API server at: http://localhost:53109&lt;/span&gt;
&lt;span style=&quot;color: #cccccc&quot;&gt;INFO     2016-12-08 12:02:58,187 dispatcher.py:197] Starting module &amp;quot;default&amp;quot; running at: http://localhost:8080&lt;/span&gt;
&lt;span style=&quot;color: #cccccc&quot;&gt;INFO     2016-12-08 12:02:58,204 admin_server.py:116] Starting admin server at: http://localhost:8000&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
アプリテストは、http://localhost:8080 で、Adminコンソールは、http://localhost:8000 でアクセスできます。

&lt;p&gt;
&lt;div style=&quot;margin-left:30px;&quot;&gt;
追記 2017/06/10&lt;br&gt;

dev_appserver.py を終了させるには &lt;strong&gt;Ctrl+c&lt;/strong&gt; を押しますが、再度起動しようとすると次のようなエラーが出る場合があります。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;google.appengine.tools.devappserver2.wsgi_server.BindError: Unable to bind localhost:8080&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;br&gt;
この場合、次のコマンドを実行してみてください（macOSやLinuxなど）。
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;lsof -P | grep &amp;#x27;:8080&amp;#x27; | awk &amp;#x27;{print $2}&amp;#x27; | xargs kill -9&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;br&gt;
参考: &lt;a href=&quot;https://stackoverflow.com/questions/15985130/apps-wont-run-on-gae-unable-to-bind-to-localhost0&quot;&gt;Apps won&#39;t run on GAE - &#39;unable to bind to localhost:0&#39;&lt;/a&gt;
&lt;/div&gt;



&lt;h5&gt;プロジェクトの切り替え&lt;/h5&gt;


デフォルト以外の複数のプロジェクトを利用している場合、プロジェクト毎に環境を作成し、切り替える必要があります。

&lt;p&gt;
新しいプロジェクトの環境は、gcloud config configurations create コマンドで作成します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;PS C:\myapp2\web2py&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;configurations&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myapp2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Created [myapp2].&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Activated [myapp2].&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


「myapp2」という環境を作成すると共に、myapp2 に環境が切り替わりました。

&lt;p&gt;
プロジェクト名の登録は、gcloud config set project コマンドです。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;PS C:\myapp2\web2py&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myapp2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Updated property [core/project].&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;
アカウント情報の登録は、gcloud auth login コマンドです。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;PS C:\myapp2\web2py&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;login&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


ブラウザ画面が開き、Googleアカントを認証します。

&lt;p&gt;
現在登録しているアカントと違なるアカウントを使用する場合は、次のコマンドを使用します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ACCOUNT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
プロジェクトを切り替える時は、gcloud config configurations activate コマンドを使用します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;PS C:\myapp\web2py&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;configurations&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;activate&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Activated [default].&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


デフォルト・プロジェクトに切り替えます。

&lt;p&gt;
現在の環境情報を参照する場合は、gcloud config list を使用します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;PS C:\myapp\web2py&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Your active configuration is: [default]&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;[compute]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;region = us-central1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;zone = us-central1-f&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[core]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;account = xxxx@gmail.com&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;disable_usage_reporting = False&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;project = myapp&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;
環境の一覧は、gcloud config configurations list を使用します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;PS C:\myapp\web2py&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;configurations&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;NAME         IS_ACTIVE  ACCOUNT              PROJECT      DEFAULT_ZONE   DEFAULT_REGION&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;default      True       xxxx@gmail.com       myapp        us-central1-f  us-central1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;myapp2       False      xxxx@gmail.com       myapp2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;





&lt;h5&gt;その他&lt;/h5&gt;

&lt;p&gt;
他にも様々なコマンドが用意されています。例えば、次のようなコマンドがあります。

&lt;ul&gt;
&lt;li&gt;
インスタンスの一覧を表示

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;instances&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;br&gt;&lt;/li&gt;

&lt;li&gt;
モジュール一覧を表示

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;n&quot;&gt;gcloud&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;services&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;br&gt;&lt;/li&gt;


&lt;li&gt;
アプリをブラウザで表示

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;gcloud app browse&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

次のようにオプションも指定できます。
&lt;dl&gt;
&lt;dt&gt;--service（-s）&lt;/dt&gt;
&lt;dd&gt;サービス（モジュール）名を指定&lt;/dd&gt;
&lt;dt&gt;--version（-v）&lt;/dt&gt;
&lt;dd&gt;バージョンを指定&lt;/dd&gt;
&lt;/dl&gt;

&lt;/li&gt;

&lt;li&gt;
SDKコンポーネントのアップデート

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;gcloud components update&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

アップデートは指示が表示されますので、そのタイミングで実行すれば良いです。

&lt;br&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
などなどです。

&lt;p&gt;&lt;br&gt;

参考:&lt;br&gt;
&lt;a href=&quot;https://cloud.google.com/sdk/docs/&quot; target=&quot;_blank&quot;&gt;Google Cloud SDK ドキュメント&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://cloud.google.com/appengine/docs/python/&quot; target=&quot;_blank&quot;&gt;Google App Engine Python Standard Environment ドキュメント&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;http://qiita.com/yuko/items/1c4ee5b081c5b6a3ac8a&quot; target=&quot;_blank&quot;&gt;ハンズオン : Google Cloud SDK 基本と認証&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;http://qiita.com/kumanoryo/items/1fbd5302fc68a3980b5e&quot; target=&quot;_blank&quot;&gt;gcloud confing configurations コマンドでconfig設定を切り替える&lt;/a&gt;











&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/3046637934638249205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/3046637934638249205'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2016/12/google-cloud-sdk.html' title='Google Cloud SDK への移行'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-3542082098223896508</id><published>2016-06-01T04:22:00.001+09:00</published><updated>2017-11-16T18:56:32.076+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google AppEngine"/><title type='text'>GAEでSSLの設定（Let’s Encrypt の導入備忘録）</title><content type='html'>&lt;div style=&quot;border: 1px dashed orange;padding:10px&quot;&gt;
---&lt;font color=&quot;red&quot;&gt;重要&lt;/font&gt;---&lt;br&gt;
GAEのSSL設定は、マネージドセキュリティという仕組みが導入され、簡単になりました。&lt;br&gt;
参考：&lt;a href=&quot;http://www.publickey1.jp/blog/17/google_app_engine_managed_ssl.html&quot; target=&quot;_blank&quot;&gt;Google App EngineでマネージドSSLが全ユーザーに無料提供&lt;/a&gt;&lt;br&gt;&lt;br&gt;

GAE設定の「&lt;a href=&quot;https://console.cloud.google.com/appengine/settings/domains&quot; target=&quot;_blank&quot;&gt;カスタムドメイン&lt;/a&gt;」画面でカスタムドメインをチェックし、『マネージドセキュリティを有効にする』ボタンを押すだけで設定が完了します。また証明書の自動更新も行われます。&lt;br&gt;
以下の記事のような作業は、行う必要はありません。（２０１７年９月１４日以降）&lt;br&gt;

&lt;/div&gt;


&lt;p&gt;&lt;br&gt;
今回はGAEのSSL設定について、備忘録を残します。

&lt;p&gt;
サーバにSSL証明書を導入することは、セキュリティの観点から推奨されています。しかしGAE（Google App Engine）上で導入するには、独特の費用の問題があり、簡単ではありませんでした。
しかし今では、導入のハードルはかなり下がってきています。

&lt;p&gt;
GAEでSSL証明書を導入する場合、以前は設定するだけ課金されました。しかし現在は、&lt;strong&gt;SNI&lt;/strong&gt; 形式を利用する場合は無料で開放されています（以前は月額９ドル課金）。&lt;strong&gt;VIP&lt;/strong&gt; 形式の場合は、現在でも月額３９ドル課金されます。しかしSNI形式でも最近では、多くのブラウザーが対応しています。

&lt;p&gt;
参考&lt;br&gt;
SNI は、グローバルIPに依存せず、ホスト名毎にSSL証明書を使い分けることができます。&lt;br&gt;
&lt;a href=&quot;https://ja.wikipedia.org/wiki/Server_Name_Indication&quot;&gt;wikipedia - Server Name Indication&lt;/a&gt;&lt;br&gt;
VIP（仮想IP）は、アプリケーションに専用のIPアドレスを割り当てます。SSL証明書も、与えられたグローバルIPに対して割り当てられます。&lt;br&gt;
&lt;a href=&quot;http://westplain.sakuraweb.com/translate/GAE/Managing-Your-App/Custom-Domains/SSL-for-a-Custom-Domain.cgi#adding_and_removing_vips&quot;&gt;GAE日本語訳 - カスタムドメインのSSL&lt;/a&gt;


&lt;p&gt;
SSL証明書自体も、年額で数万するという認識でした（グローバルサインのクイック認証SSLで、定価34800円など）。しかしSSL/TSL普及を目指す非営利団体の登場などにより、現在では無料のSSL証明書を利用することも可能になっています。

&lt;p&gt;
今回無料のSSL証明書である、Let’s Encrypt をGAEに導入します。この手順は既にネット上で公開されています。私もそれらの情報を参考に設定しましたが、一つ問題があります。それは Let’s Encrypt が発行する証明書の有効期限は９０日と非常に短いのです。Let’s Encrypt では自動更新ツールを提供することにより、短い有効期限の問題の解決策を示していますが、現在のところGAE上ではこのツールを利用することが出来ないようです。

&lt;p&gt;
今回備忘録として設定方法を記事にするのは、サーバ側で何らかの解決策が示されるまで、当分定期的にSSL証明書を手動で登録更新を続ける必要があるためです。

&lt;p&gt;
今回参考にした記事・サイト&lt;br&gt;
&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let’s Encrypt&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;http://blog.seafuj.com/lets-encrypt-on-google-app-engine&quot;&gt;Let’s Encrypt on Google App Engine&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;http://qiita.com/koki_cheese/items/0b1d092377645157fae8#%E3%81%BE%E3%81%A8%E3%82%81&quot;&gt;Let&#39;s Encryptの証明書をGoogleAppEngineに設定して独自ドメインで運用する&lt;/a&gt;&lt;br&gt;

&lt;h5&gt;Cloud Shell にてSSL証明書発行&lt;/h5&gt;

Google Cloud Console　から、Cloud Shell を開きます。ちなみに Cloud Shell は 2016年中は無料だそうです。
&lt;p&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9ud5Z1iwINratm40euXLH5ygH-OpDBHsjaUKD-K0lJ6QavdUtlfhJjlz8-QkN9xGQyVlEuyGkoFSERnWHP1zxpI0FKSaV_pO8zFVHi20iIlnDNDOglPkALD67WZCiaErS9qs2pe2XbIA/s1600/gae01.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9ud5Z1iwINratm40euXLH5ygH-OpDBHsjaUKD-K0lJ6QavdUtlfhJjlz8-QkN9xGQyVlEuyGkoFSERnWHP1zxpI0FKSaV_pO8zFVHi20iIlnDNDOglPkALD67WZCiaErS9qs2pe2XbIA/s640/gae01.jpg&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
ブラウザの下部にシェルが表示されます。&lt;br&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiye-r_oWMc-zKsOBb3zXQD6iX7wrkfGa5pQmV9i8Wsx0xJAMgi7yTdrStKTZb6u0X5zXKvdWG6trgk6IIRw7Z17RML_NK43RjSNMYYwFq4Qt-HYfquXVR7_0JjK9KYPHtB1JP9FuOe35I/s1600/gae02.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiye-r_oWMc-zKsOBb3zXQD6iX7wrkfGa5pQmV9i8Wsx0xJAMgi7yTdrStKTZb6u0X5zXKvdWG6trgk6IIRw7Z17RML_NK43RjSNMYYwFq4Qt-HYfquXVR7_0JjK9KYPHtB1JP9FuOe35I/s640/gae02.jpg&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
次のコマンドで Let’s Encrypt モジュールのクーロンを作成します。&lt;br&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;git clone https://github.com/letsencrypt/letsencrypt&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
Let’s Encrypt のディレクトリに移動します。&lt;br&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;cd letsencrypt&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
下のコマンドで、チャレンジ・レスポンス確認モードで動作させます（この時モジュールがインストールされるため、時間が掛かります）。&lt;br&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;sudo ./letsencrypt-auto -a manual certonly&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
リカバリ用にメールアドレスを入力します。&lt;br&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh63oLzRIy-9ACJxHVh_ypBU5OdNI6P7oJhiGUEQ7lHlDTT-CM-O6PEBGBba0vCPqFiDZ9h7dKubU1VPnIjxhSUKdfzEU1hyphenhyphenXR4vGW2gKqXhpSbkGJqePMptzfJ0BcDdu2uapNPJXr18lY/s1600/gae01.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh63oLzRIy-9ACJxHVh_ypBU5OdNI6P7oJhiGUEQ7lHlDTT-CM-O6PEBGBba0vCPqFiDZ9h7dKubU1VPnIjxhSUKdfzEU1hyphenhyphenXR4vGW2gKqXhpSbkGJqePMptzfJ0BcDdu2uapNPJXr18lY/s640/gae01.jpg&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
利用規約に同意します。&lt;br&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbPOl6v6wPdJZF-pGnMmXE1ev_h9_mZHayuaaTvGxvv0pumfMyvb6zqq75K87fA-9No9-6gtzkrA27on5V-KB-irx4DsGwaH9ts9n8zumIEOXbPZyaHUL3UnJkTeSvZr-228jMmSKV8KI/s1600/gae02.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbPOl6v6wPdJZF-pGnMmXE1ev_h9_mZHayuaaTvGxvv0pumfMyvb6zqq75K87fA-9No9-6gtzkrA27on5V-KB-irx4DsGwaH9ts9n8zumIEOXbPZyaHUL3UnJkTeSvZr-228jMmSKV8KI/s640/gae02.jpg&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
独自ドメインを入力します。&lt;br&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBWXV6xE8pwg3NVh_62ccUUT5ImYpqC9AH1VFEqslUwVY3_hz7KvrBxsVFzjlasOf06xaOrElIHNW_61LNq-O2bRlPpGGhcEdSZo6GtrX-w_2cGs1JGSICd336vKSq5HuA12NgSiFDYns/s1600/gae03.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBWXV6xE8pwg3NVh_62ccUUT5ImYpqC9AH1VFEqslUwVY3_hz7KvrBxsVFzjlasOf06xaOrElIHNW_61LNq-O2bRlPpGGhcEdSZo6GtrX-w_2cGs1JGSICd336vKSq5HuA12NgSiFDYns/s640/gae03.jpg&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
マニュアルモードでの動作を確認します。&lt;br&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6hzwrqwC5hSc02SupNL1QLman6DwZ-TDibGBWBOfAbn7-uqXzC2lQ49_cO7t0jpnDm2KlQGAProHdpggCuTOGY0ZjTmnknC0LvfZDYRQrTMMiOXtU1CXVKsn1OO40vAFL0GhhuOlIef0/s1600/gae06.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6hzwrqwC5hSc02SupNL1QLman6DwZ-TDibGBWBOfAbn7-uqXzC2lQ49_cO7t0jpnDm2KlQGAProHdpggCuTOGY0ZjTmnknC0LvfZDYRQrTMMiOXtU1CXVKsn1OO40vAFL0GhhuOlIef0/s640/gae06.jpg&quot; /&gt;&lt;/a&gt;

&lt;p&gt;次のメッセージが表示されます。&lt;br&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnAVvIkxnGIgmSFjfeFJStPTfIB5_JvZOja2yW1n0f99wrBAsGPMVKyQj7em2ps5oOtT2Q8vwsYlNAtW-lPAtkhftBEkiekX752zRfkyH6cq_cThvRByFc0Q-lvQmCub2MwLPlHpwIVpI/s1600/gae05.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnAVvIkxnGIgmSFjfeFJStPTfIB5_JvZOja2yW1n0f99wrBAsGPMVKyQj7em2ps5oOtT2Q8vwsYlNAtW-lPAtkhftBEkiekX752zRfkyH6cq_cThvRByFc0Q-lvQmCub2MwLPlHpwIVpI/s640/gae05.jpg&quot; /&gt;&lt;/a&gt;

&lt;p&gt;独自ドメインの次のURLにアクセスすると、指示されたレスポンスコードを返すように設定します。&lt;br&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;http://独自ドメイン/.well-known/acme-challenge/チャレンジコード&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;いろいろ方法がありますが、app.yaml に次の設定を追加するのが簡単です。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/.well-known/acme-challenge/?(.{5}).*&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;static_files&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;applications/myapp/static/letsencrypt/\1.txt&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;applications/myapp/static/letsencrypt/(.+)&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;mime_type&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;text/plain&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;applications/myapp/static/letsencrypt/ ディレクトリに、チャレンジコードの頭５桁の名前を付けたテキストファイルの中身に、レスポンスコードを入れて、ファイルを生成します。例えば、

&lt;p&gt;
l1b83dAg6K-b10wHpoFguNo9b4iOIOAkiHtEkT3yhiE　というチャレンジコードだったら、 l1b83.txt というファイルを作成し、中身にレスポンスコードを入れます。

&lt;p&gt;
これらのアプリケーションファイルのGAEへのアップロードが完了したら、ENTERキーを押して処理を続行し、正常に完了したら証明書が生成されています。

&lt;h5&gt;SSL証明書のセット&lt;/h5&gt;

SSL証明書は Cloud Shell 上で、 &lt;br&gt;&lt;br&gt;

/etc/letsencrypt/live/独自ドメイン/fullchain.pem　　→ 公開鍵証明書&lt;br&gt;
/etc/letsencrypt/live/独自ドメイン/privkey.pem　　　→　RSA秘密鍵&lt;br&gt;&lt;br&gt;

ファイルが生成されています。Cloud Consolel の「設定」→「SSL証明書」→「新しい証明書をアップロード」 で次の画面を開きます。&lt;br&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibGvGSBamFARVFPbtlFH7Uj8c8SS1VFJXt9anjC3VLFoLhgqn5hXcFaJBkpoRRror5iFCN7jcIGEtqob_rcBXNzxnLCuG953eqkTCwUfztS7xnyokWWRzVhqpogG3Veuz-0JFCfGLDsUs/s1600/gae07.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibGvGSBamFARVFPbtlFH7Uj8c8SS1VFJXt9anjC3VLFoLhgqn5hXcFaJBkpoRRror5iFCN7jcIGEtqob_rcBXNzxnLCuG953eqkTCwUfztS7xnyokWWRzVhqpogG3Veuz-0JFCfGLDsUs/s640/gae07.jpg&quot; style=&quot;border: 1px solid #e2e2e2;&quot; /&gt;&lt;/a&gt;

&lt;p&gt;Cloud Shell の次のコマンドで公開鍵証明書の中身を表示します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;sudo less /etc/letsencrypt/live/独自ドメイン/fullchain.pem&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
-----BEGIN CERTIFICATE-----&lt;br&gt;
xxxxxxxxxxxxxxxxxxxxxxxxxxx&lt;br&gt;
xxxxxxxxxxxxxxxxxxxxxxxxxxx&lt;br&gt;
xxxxxxxxxxxxxxxxxxxxxxxxxxx&lt;br&gt;
-----END CERTIFICATE-----&lt;br&gt;
&lt;p&gt;
BEGINの行からENDの行までコピーして、公開鍵証明書の画面に貼り付けます。

&lt;p&gt;
&lt;div style=&quot;border: 1px solid #e2e2e2;padding:10px;margin:10px;&quot;&gt;
追記（&lt;font color=&quot;#ff0000&quot;&gt;注意&lt;/font&gt;）: 
fullchain.pem には、公開鍵証明書と共に中間CA証明書が追記されています。つまり、

&lt;p&gt;
-----BEGIN CERTIFICATE-----&lt;br&gt;
公開鍵証明書&lt;br&gt;
-----END CERTIFICATE-----&lt;br&gt;
-----BEGIN CERTIFICATE-----&lt;br&gt;
中間CA証明書&lt;br&gt;
-----END CERTIFICATE-----&lt;br&gt;

&lt;p&gt;
という構成になっていますので、公開鍵証明書のBEGINから中間CA証明書のENDまでコピーします。
&lt;/div&gt;

&lt;p&gt;
同様にRSA秘密鍵も、

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;sudo openssl rsa -inform pem -in /etc/letsencrypt/live/独自ドメイン/privkey.pem -outform pem | less&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

で中身を表示します。

&lt;p&gt;
-----BEGIN RSA PRIVATE KEY-----&lt;br&gt;
xxxxxxxxxxxxxxxxxxxxxxxxxxx&lt;br&gt;
xxxxxxxxxxxxxxxxxxxxxxxxxxx&lt;br&gt;
xxxxxxxxxxxxxxxxxxxxxxxxxxx&lt;br&gt;
-----END RSA PRIVATE KEY-----&lt;br&gt;

&lt;p&gt;
同様にBEGINからENDの行までをコピーし、画面に貼り付けます。完了したらSSL証明書をアップロードします。

&lt;p&gt;
最後に、アップロードしたSSL証明書のリンクをクリックし、「次のカスタム ドメインに対して SSL を有効にします」の項目でカスタムドメインにチェックを入れて、保存ボタンを押します。これによって、SSL証明書が有効に動作します。&lt;br&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOXk-MlPHYOTzQgFTOu_XjryeXS3gLdSM_d57CcLxQalMlRmaNCsNcuurtZ6O0zgjYLfOfe-j9biVVbaM16BSYQW5hYdhyphenhyphen45P1KpVSlbvcZ8G13MpxmrlazXBdtORvb1aN30QyIp5H2DQ/s1600/gae08.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOXk-MlPHYOTzQgFTOu_XjryeXS3gLdSM_d57CcLxQalMlRmaNCsNcuurtZ6O0zgjYLfOfe-j9biVVbaM16BSYQW5hYdhyphenhyphen45P1KpVSlbvcZ8G13MpxmrlazXBdtORvb1aN30QyIp5H2DQ/s640/gae08.jpg&quot; style=&quot;border: 1px solid #e2e2e2;&quot; /&gt;&lt;/a&gt;

&lt;p&gt;&lt;br&gt;

以上で、SSL証明書の設定は完了します。難しくはないのですが、分かり難いです。この作業を９０日毎に行う必要があります（更新では証明書を生成して貼り付けるだけですが・・・）。GAEでも自動で更新するようになれば楽になります。今後に期待しています。&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/3542082098223896508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/3542082098223896508'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2016/06/gaessllets-encrypt.html' title='GAEでSSLの設定（Let’s Encrypt の導入備忘録）'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9ud5Z1iwINratm40euXLH5ygH-OpDBHsjaUKD-K0lJ6QavdUtlfhJjlz8-QkN9xGQyVlEuyGkoFSERnWHP1zxpI0FKSaV_pO8zFVHi20iIlnDNDOglPkALD67WZCiaErS9qs2pe2XbIA/s72-c/gae01.jpg" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-8021811471592365640</id><published>2015-07-01T00:28:00.001+09:00</published><updated>2023-01-06T23:47:41.816+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google AppEngine"/><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>web2py GAEのカーソルとbelongs（IN演算子）</title><content type='html'>GAE（Google App Engine）の Datastore環境でカーソルを使用した場合、&lt;strong&gt;belongs&lt;/strong&gt; メソッドでエラーが出て動きません。これは記述を変更することで、動作することが解りました。この件について、メモ書き記事にします。

&lt;p&gt;
belongs は、SQLの&lt;strong&gt;IN&lt;/strong&gt;演算子に変換されます。belongs の詳しい説明は、次のリンクを参照ください。

&lt;p&gt;
参考: &lt;a href=&quot;http://docs-hiho.appspot.com/web2py_dal/class/class_expression.html#dal.Expression.belongs&quot;&gt;web2py補足ドキュメント - Expression.belongs(value) &lt;/a&gt;

&lt;h5&gt;テスト用コード&lt;/h5&gt;

&lt;p&gt;
次のようなコードを考えます。

&lt;p&gt;
モデル

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;define_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;person&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%(name)s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;define_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;dog&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;owner_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;birthday&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;date&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requires&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IS_DATE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;%Y-%m-&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
コントローラ

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;today&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;date_last_year&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;today&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;days&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;365&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;dbset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date_last_year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
&lt;span class=&quot;hll&quot;&gt;        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;owner_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;belongs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
このコードは、GAE環境でも特に問題なく動作します。ちなみにコントローラのコードの９行目で belongs を使用しています。

&lt;h5&gt;エラーが発生するコード&lt;/h5&gt;

&lt;p&gt;
それではGAE環境で、エラーの発生するコードを見てみましょう。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;today&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;date_last_year&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;today&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;days&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;365&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;dbset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date_last_year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;owner_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;belongs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;limitby&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
１０行目の select メッソッドに、&lt;strong&gt;limitby&lt;/strong&gt; を設定しました。limitby は、セレクトするレコード数を指定するオプションです。

&lt;p&gt;
参考: &lt;a href=&quot;http://docs-hiho.appspot.com/web2py_dal/class/class_set.html#dal.Set.select&quot;&gt;web2py補足ドキュメント - Set.select([*fields, **attributes]) &lt;/a&gt;

&lt;p&gt;
GAE以外の環境では問題なく動きます。GAE環境では、次のようなエラーメッセージがログに記録されます。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;BadArgumentError: _MultiQuery with cursors requires __key__ order&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h5&gt;解決策&lt;/h5&gt;

&lt;p&gt;
このエラーが発生するのは、&lt;strong&gt;NDB API&lt;/strong&gt; を使った場合のようです。NDB は Python の次世代 Datastore 用モジュールで、数年前に登場しました。web2py でもGAE環境の場合は、コードを NDB API 用に変換するようになっています。

&lt;p&gt;
参考: &lt;br&gt;
&lt;a href=&quot;http://stackoverflow.com/questions/12449197/badargumenterror-multiquery-with-cursors-requires-key-order-in-ndb&quot;&gt;BadArgumentError: _MultiQuery with cursors requires __key__ order in ndb&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://cloud.google.com/appengine/docs/python/ndb/queries#cursors&quot;&gt;NDB Datastore API - Query Cursors&lt;/a&gt;

&lt;p&gt;
NDB ではクエリーとして、&lt;strong&gt;IN&lt;/strong&gt; / &lt;strong&gt;OR&lt;/strong&gt; / &lt;strong&gt; !=&lt;/strong&gt; の各演算子とカーソルを同時に使用した場合、上記のエラーが発生する仕様になっています。

&lt;p&gt;
「ん？、カーソルは使用していないぞ」 と思われるかもしれませんが、web2py では limitby オプションを利用した場合、カーソルを使用するようになっています。

&lt;p&gt;
問題解決のためには、クエリーで使用するフィールドでソートしてあげればよいです。具体的には、次のようにコード変更します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;today&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;date_last_year&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;today&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;days&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;365&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;dbset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date_last_year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;owner_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;belongs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;limitby&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;                        &lt;span class=&quot;n&quot;&gt;orderby&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;owner_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
１１行目の select メソッドで、 &lt;strong&gt;orderby&lt;/strong&gt; オプションを指定します。

&lt;p&gt;
参考: &lt;a href=&quot;http://docs-hiho.appspot.com/web2py_dal/class/class_set.html#dal.Set.select&quot;&gt;web2py補足ドキュメント - Set.select([*fields, **attributes]) &lt;/a&gt;

&lt;p&gt;
ここで気をつける事は、ソートフィールドにクエリーで使用するフィールドを含めると共に、主キーのフィールド（idフィールド）を最後に足します。idフィールドがソートに含まれないと、プログラムは動作しません。

&lt;p&gt;
ちょっとレアなケースの仕様のようですが、解り難かったので記事にしました。
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8021811471592365640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8021811471592365640'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2015/07/web2py-gaebelongsin.html' title='web2py GAEのカーソルとbelongs（IN演算子）'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-9009999767286455579</id><published>2015-06-24T03:12:00.001+09:00</published><updated>2023-01-06T23:49:46.178+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google AppEngine"/><title type='text'>GAE、Modulesの設定 ②</title><content type='html'>&lt;a href=&quot;http://todayspython.blogspot.com/2015/06/gaemodules.html&quot;&gt;前回&lt;/a&gt; の続きです。GAE(Google App Engine)の一機能である &lt;strong&gt;Modules API&lt;/strong&gt;の設定について、具体的に説明していきます。

&lt;p&gt;
&lt;div style=&quot;border: 1px dashed orange;padding:10px&quot;&gt;
GAEのデプロイツールは、従来の APPCFG が GCLOUD に変更になりました。移行方法などは次のリンクの記事を参考にしてください。&lt;br&gt;
→　&lt;a href=&quot;http://todayspython.blogspot.com/2016/12/google-cloud-sdk.html&quot;&gt;Google Cloud SDK への移行&lt;/a&gt;
&lt;/div&gt;


&lt;h5&gt;yaml 定義ファイルの作成&lt;/h5&gt;

&lt;p&gt;
Moduleを作成するには、そのための yaml ファイルを作成する必要があります。取り敢えず、バックエンド・ジョブ用の例を示します。

&lt;p&gt;
back_job.yaml

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;myapp&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;back-job&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;1-00&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;api_version&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;l-Scalar-Plain&quot;&gt;instance_class&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;B1&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;basic_scaling&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;max_instances&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;idle_timeout&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;1m&lt;/span&gt;

&lt;span class=&quot;l-Scalar-Plain&quot;&gt;runtime&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;python27&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;threadsafe&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;true&lt;/span&gt;

&lt;span class=&quot;l-Scalar-Plain&quot;&gt;handlers&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;.*&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;gaehandler.wsgiapp&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;admin&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;


&lt;p&gt;
&lt;strong&gt;back_job.yaml&lt;/strong&gt; ファイルを作成します。GAEのアプリケーション情報を記述する app.yaml とほぼ 同じ形式ですが、二行目の &lt;strong&gt;module:&lt;/strong&gt;  に Module名を記述します。ここでは、&lt;strong&gt;back-job&lt;/strong&gt; という名前をつけます。 

&lt;p&gt;
余談ですが、app.yaml にも module: を記述できます。しかし記述しないと、&lt;strong&gt;default&lt;/strong&gt; という Module名が記述されたと見なされます。つまりすべてのアプリケーションのインスタンスは、Module下で動いていることになります（何も記述しないと default）。

&lt;p&gt;
もう一つ注目して欲しい項目として、&lt;strong&gt;instance_class:&lt;/strong&gt; と &lt;strong&gt;basic_scaling:&lt;/strong&gt; があります。それぞれ前回説明した、インスタンス・クラスとスケール・タイプを指定しています。ここではインスタンスクラスは B1 で、スケール・タイプは Basic Scaling を選択しました。これによって制限がないタスクを実行可能です。max_instances: は上限のインスタンス数を指定しますが、必ず記述する必要があります。

&lt;p&gt;
&lt;strong&gt;idle_timeout:&lt;/strong&gt; はオプションの設定ですが、Basic Scaling の場合は指定しないと、インスタンスが停止するまでのアイドル時間がデフォルト値の１０分になってしまいます。毎時間実行するジョブの場合、一日あたり４時間分も余分なアイドル時間に取られてしまいます。費用削減のためにも、なるべく少ない時間を指定した方が良いでしょうね。

&lt;p&gt;
&lt;strong&gt;handlers:&lt;/strong&gt; で、すべてのURLを処理するようにしていますが、login: admin オプションを付けています。Cronで実行するジョブは adminユーザ権限で実行されるため、ジョブの実行には問題ないと同時に不正なアクセスを防止します。

&lt;h5&gt;Moduleインスタンスのスタートアップ設定&lt;/h5&gt;

&lt;p&gt;
ちょっとここから？？？、となる設定です。前回説明した３つのスケール・タイプの内 Manual Scaling と Basic Scaling では、インスタンスのスタートアップのために特殊な設定を行うことが必要です。それはスタートアップ時に、GAEからのGETリスエストが &lt;strong&gt;/_ah/start&lt;/strong&gt; のURLに送信されます。これに応答する必要があります。具体的には 、HTTPステータスコードの200〜299までか404を返すことが必要です。

&lt;p&gt;
私は最初次のように、静的HTMLファイルを返せば良いのかなと勘違いしていました。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# この設定は動きません。&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# This setting does not work.&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;handlers&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/_ah/start&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;static_files&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;applications/myapp/static/200.html&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;applications/myapp/static/200.html&lt;/span&gt;
&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;.*&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;gaehandler.wsgiapp&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;admin&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
この設定では Module は動きません。なぜなら、 /_ah/start リスエスト共にインスタンスを起動してイニシャライズを行うことが必要だからです。静的HTMLファイルを返すだけでは、GAEのインスタンスは起動しません（逆に言えば、静的HTMLだけのアプリなら、GAEではインスタンス費用を払う必要がありません）。

&lt;p&gt;
インスタンスを起動するため、web2pyフレームワークの場合なら、_ah.py コントローラを作成し次のように記述します。

&lt;p&gt;
_ah.py

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;c&quot;&gt;# -*- coding: utf-8 -*-&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;200&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
これによって、インスタンスが起動する共にステータスコードの200を返すことができます。

&lt;p&gt;
この他に、インスタンス終了時に &lt;strong&gt;/_ah/stop&lt;/strong&gt; というリクエストが送らてきますが、これに関してはアプリケーション側で対応する必要はないようです。

&lt;h5&gt;タスクやURLのディスパッチ&lt;/h5&gt;

&lt;p&gt;
最も簡単にタスクを Module に割り当てるには、cron.yaml の &lt;strong&gt;target:&lt;/strong&gt; パラメータに割り当てる Module名を記述します。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;cron&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;my task&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/myapp/job/task&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;schedule&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;every 1 hours&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;back-job&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
もし、CronでないタスクやURLを使用する場合は、&lt;strong&gt;dispatch.yaml&lt;/strong&gt; を作成します。

&lt;p&gt;
dispatch.yaml

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;myapp&lt;/span&gt;

&lt;span class=&quot;l-Scalar-Plain&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;*/job/*&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;back-job&lt;/span&gt;

&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;*/nightjob/*&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;back-job&lt;/span&gt;
&lt;/pre&gt;&lt;div style=&quot;text-align:right;padding-right:5px;font-size:small;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;
URL毎に Module を指定することができます。

&lt;p&gt;
これまた余談ですが、GAEにアップロードした dispatch.yaml の設定を削除する方法がないみたいです。設定を無効にする場合は、dispatch.yaml ファイルを削除するのではなく、設定にコメントを入れてください。これによって設定が無効になります。

&lt;h5&gt;Module のアップロード&lt;/h5&gt;

&lt;p&gt;
設定した Module をGAEにアップロードは、GAEランチャーのアップロード機能では対応できないようです。コマンドラインやターミナルやから、次のコマンドを送ってください。

&lt;div class=&quot;highligh&quot; style=&quot;background: #202020; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #202020;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #d0d0d0&quot;&gt;python appcfg.py update back_job.yaml&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;br&gt;
もしくは
&lt;br&gt;&lt;br&gt;

&lt;div class=&quot;highligh&quot; style=&quot;background: #202020; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #202020;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #d0d0d0&quot;&gt;appcfg.py update back_job.yaml&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
この他、app.yaml 側のアップロードも別途必要です。

&lt;p&gt;
もし dispatch.yaml だけを更新したい場合は、次のようなコマンドもあるようです。

&lt;div class=&quot;highligh&quot; style=&quot;background: #202020; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #202020;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #d0d0d0&quot;&gt;appcfg.py update_dispatch ./&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Modules API で一番嫌なのは、Module毎にアップロードする必要があることです。面倒な場合、必要なアップロードを全部繋げてバッチファイルを作成しても良いとは思います。

&lt;h5&gt;最後に&lt;/h5&gt;
&lt;p&gt;
以上で Modules API の説明を終わりますが、バックエンドの無制限の環境でもジョブが停止することがあります。それはメモリの割当を超えたなどの原因が考えられます。このためジョブを適度な長さに切って、その都度タスクキューに送るなどの工夫が必要になってきます。タスクキューを使い始めると、いろいろプログラムの工夫ができるようになります。タスクキューを使ったことがない方は、Modules API と一緒に使ったら幸せになれると思います。

&lt;p&gt;
参考: &lt;a href=&quot;https://cloud.google.com/appengine/docs/python/config/queue&quot;&gt;Python Task Queue Configuration&lt;/a&gt;

&lt;p&gt;
ところで、暇つぶし用に作ったアプリケーションがあります。最近のメジャーなフレームワークなどをぶっ込んでみました（笑）。

&lt;p&gt;
GAE + web2py + Bootstrap + AngularJS + などなど
&lt;br&gt;
↓↓↓

&lt;div style=&quot;margin:20px 0&quot;&gt;
&lt;a href=&quot;http://hima.click/&quot; imageanchor=&quot;1&quot;  height=&quot;40&quot; width=&quot;260&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7Mv8OUfopRaV62w2gBsmc-WKViouunt0u02rSI3-YioM1w-VIWn_nOf1hefL7ZP-4c4XtvPygVWinXQNxXt3DcNMjGhi7mp_vaxsLYErdtgVfJ72d5VfKUZNlsUpDoQp1EV1RQloTgzM/s320/hima_clicl.jpg&quot; / title=&quot;ひま☆クリック&quot; alt=&quot;ひま☆クリック&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;

↑↑↑&lt;br&gt;
よかったら使ってみてください。&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/9009999767286455579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/9009999767286455579'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2015/06/gaemodules_24.html' title='GAE、Modulesの設定 ②'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7Mv8OUfopRaV62w2gBsmc-WKViouunt0u02rSI3-YioM1w-VIWn_nOf1hefL7ZP-4c4XtvPygVWinXQNxXt3DcNMjGhi7mp_vaxsLYErdtgVfJ72d5VfKUZNlsUpDoQp1EV1RQloTgzM/s72-c/hima_clicl.jpg" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-8497944525845944538</id><published>2015-06-22T22:13:00.001+09:00</published><updated>2023-01-06T23:50:45.560+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google AppEngine"/><title type='text'>GAE、Modulesの設定 ①</title><content type='html'>GAE（Google App Engine）の &lt;strong&gt;Modules API&lt;/strong&gt; について、設定で試行錯誤したのでメモを兼ねた記事にします。

&lt;br /&gt;
&lt;h5&gt;
Modules API について&lt;/h5&gt;
既に使っている方も多いと思いますが、Modules API について簡単に説明します。

&lt;br /&gt;
GAEには以前から、&lt;strong&gt;Backends API&lt;/strong&gt; という仕組みがありました。これは常時起動しているインスタンスで、主にCronなどのジョブを専門に実行する環境です。Backends API を利用した場合、次の利点があると思います。

&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;フロントエンドの環境では１０分を超える処理はできませんでしたが、Backends API では制限はありません。&lt;/li&gt;
&lt;li&gt;フロントエンドとバックエンドで環境を分けることができます。非常に重い処理に対して、強力なCPUタイプを割り当てるなどの設定が可能です。&lt;/li&gt;
&lt;/ul&gt;
しかし Backends API は、２０１４年に非推奨の機能になってしまいました。 

参考: &lt;a href=&quot;https://cloud.google.com/appengine/docs/python/config/backends&quot;&gt;Backends API&lt;/a&gt;

&lt;p&gt;
代わりに登場したのが、 &lt;strong&gt;Modules API&lt;/strong&gt; です。フロントエンド・バックエンドに関係なく、アプリケーションの下に Modules という環境があり、その下にバージョン、更に下に実行環境であるインスタンスがある構成です。&lt;br&gt;


&lt;a href=&quot;https://cloud.google.com/appengine/docs/python/modules/&quot;&gt;&lt;img src=&quot;https://cloud.google.com/appengine/docs/images/modules_hierarchy.svg&quot; width=&quot;600&quot; /&gt;&lt;/a&gt;

&lt;br /&gt;
参考: &lt;a href=&quot;https://cloud.google.com/appengine/docs/python/modules/&quot;&gt;App Engine Modules in Python&lt;/a&gt;


&lt;p&gt;
Backends API との違いとして、次の点が挙げられると思います。

&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Module は幾つか作成できます（無償で５、有償では２０個まで）。処理タイプによって Module を切り替えることが可能です（Backends API でも処理毎にCPUタイプを切り替えることが可能でしたが・・・）。&lt;/li&gt;
&lt;li&gt;Backends API ではバージョンはなかったですが、Modules API ではバージョンを分けることが可能になりました。&lt;/li&gt;
&lt;li&gt;フロントエンドの処理でも、特定のURLだけ強力なCPU環境の Module を割り当てることが可能になりました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
スケール・タイプ と インスタンス・クラス&lt;/h5&gt;
Modules API との関連で、CPUに関するスケール・タイプとインスタンス・クラスを理解しておく必要があります。簡単にですが、解説してみたいと思います。

&lt;br /&gt;
以前はなかったと思いますが、GAEに「スケール・タイプ」と「インスタンス・クラス」という概念が導入されました。スケール・タイプは処理に応じて、どのようにインスタンスが増えていくのかの設定です。またインスタンス・クラスは、CPUとメモリの割り当て種類です。

&lt;table border=&quot;1&quot; bordercolor=&quot;#B0B0B0&quot; cellpadding=&quot;3&quot; cellspacing=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr align=&quot;left&quot; bgcolor=&quot;#d0d0d0&quot;&gt;&lt;th&gt;スケール&lt;br /&gt;
・タイプ&lt;/th&gt;&lt;th&gt;Deadlines&lt;/th&gt;&lt;th&gt;CPU/Memory&lt;/th&gt;&lt;th&gt;Scaling&lt;/th&gt;&lt;th&gt;Free Daily Usage Quota&lt;/th&gt;&lt;/tr&gt;
&lt;tr align=&quot;left&quot;&gt;&lt;th&gt;Automatic Scaling&lt;/th&gt;&lt;td width=&quot;180&quot;&gt;HTTPリクエスト: 60秒まで&lt;br /&gt;
タスク: 10分まで&lt;/td&gt;&lt;td width=&quot;130&quot;&gt;F1, F2, F4, F4_1G から選択&lt;/td&gt;&lt;td&gt;自動スケール&lt;/td&gt;&lt;td&gt;28時間インスタンス&lt;/td&gt;&lt;/tr&gt;
&lt;tr align=&quot;left&quot;&gt;&lt;th&gt;Manual Scaling&lt;/th&gt;&lt;td&gt;リクエスト: 無制限&lt;br /&gt;
タスク: 24時間まで&lt;/td&gt;&lt;td&gt;B1, B2, B4, B4_1G, B8 から選択&lt;/td&gt;&lt;td&gt;マニュアルによるスケール&lt;/td&gt;&lt;td&gt;8時間インスタンス&lt;/td&gt;&lt;/tr&gt;
&lt;tr align=&quot;left&quot;&gt;&lt;th&gt;Basic Scaling&lt;/th&gt;&lt;td&gt;Manual Scalingと同じ&lt;/td&gt;&lt;td&gt;Manual Scalingと同じ&lt;/td&gt;&lt;td&gt;最大インスタンス数まで処理量に応じてスケール&lt;/td&gt;&lt;td&gt;Manual Scalingと同じ&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot; bordercolor=&quot;#B0B0B0&quot; cellpadding=&quot;3&quot; cellspacing=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr align=&quot;left&quot; bgcolor=&quot;#d0d0d0&quot;&gt;&lt;th&gt;インスタンス・クラス&lt;/th&gt;&lt;th&gt;メモリ&lt;/th&gt;&lt;th&gt;CPU&lt;/th&gt;&lt;th&gt;時間当たり費用&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B1&lt;/td&gt;
&lt;td&gt;128 MB&lt;/td&gt;
&lt;td&gt;600 Mhz&lt;/td&gt;
&lt;td&gt;$0.05&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B2&lt;/td&gt;
&lt;td&gt;256 MB&lt;/td&gt;
&lt;td&gt;1.2 Ghz&lt;/td&gt;
&lt;td&gt;$0.10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B4&lt;/td&gt;
&lt;td&gt;512 MB&lt;/td&gt;
&lt;td&gt;2.4 Ghz&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B4_1G&lt;/td&gt;
&lt;td&gt;1024 MB&lt;/td&gt;
&lt;td&gt;2.4 Ghz&lt;/td&gt;
&lt;td&gt;$0.30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B8&lt;/td&gt;
&lt;td&gt;1024 MB&lt;/td&gt;
&lt;td&gt;4.8 Ghz&lt;/td&gt;
&lt;td&gt;$0.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F1&lt;/td&gt;
&lt;td&gt;128 MB&lt;/td&gt;
&lt;td&gt;600 Mhz&lt;/td&gt;
&lt;td&gt;$0.05&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F2&lt;/td&gt;
&lt;td&gt;256 MB&lt;/td&gt;
&lt;td&gt;1.2 Ghz&lt;/td&gt;
&lt;td&gt;$0.10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F4&lt;/td&gt;
&lt;td&gt;512 MB&lt;/td&gt;
&lt;td&gt;2.4 Ghz&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F4_1G&lt;/td&gt;
&lt;td&gt;1024 MB&lt;/td&gt;
&lt;td&gt;2.4 Ghz&lt;/td&gt;
&lt;td&gt;$0.30&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
参考: &lt;a href=&quot;https://cloud.google.com/appengine/docs/python/modules/&quot;&gt;App Engine Modules in Python&lt;/a&gt;

&lt;p&gt;
リクエストの制限のない Module にするには、スケール・タイプを Manual Scaling か Basic Scaling にする必要があります。

&lt;br /&gt;
因みにGAEでは、無償のインスタンス割り当てがあります。フロントエンドである Automatic Scaling Modules で一日あたり２８時間インスタンス、バックエンドの Basic and Manual Scaling Modules で一日あたり８時間インスタンスです。無償分を余すことなく使って費用を削減するためにも、Modules API を使用する必要があります。

&lt;p&gt;
前置きが長くなったので、&lt;a href=&quot;http://todayspython.blogspot.com/2015/06/gaemodules_24.html&quot;&gt;次回&lt;/a&gt;に続きます。
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8497944525845944538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8497944525845944538'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2015/06/gaemodules.html' title='GAE、Modulesの設定 ①'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-5180728704957902167</id><published>2015-04-12T11:16:00.001+09:00</published><updated>2016-01-21T22:50:14.654+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>web2py アップグレード豆知識</title><content type='html'>&lt;h5&gt;web2pyアップグレード&lt;/h5&gt;
作成したアプリケーションを、新しいバージョンの web2py に適用する場合は、幾つか方法があります。代表的な方法は、

&lt;div style=&quot;margin:10px;border: 1px green dotted;&quot;&gt;
&lt;ol  type=&quot;a&quot;&gt;
&lt;li&gt;web2py管理画面の「アップグレード」ボタンを押す&lt;/li&gt;
&lt;li&gt;新しいバージョンのweb2pyをダウンロードし、applicationsフォルダに作成したアプリケーションのフォルダを丸ごとコピーする&lt;/li&gt;
&lt;li&gt;（デベロッパー版web2pyを利用している場合） git pull コマンドで更新する&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

&lt;p&gt;
一番目の方法（a）は、web2pyの管理画面にあるアップグレードボタンを押すと、更新が完了します。
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi17ievEazp3jiCLgDiInIW_XcTT9bb1xjUTxSjzIU0S7qaNv4BBtq_N-NNbiidQiwO8d3iy7k7BV9e5SriMLV2fIMtf9TPVx_voquga_e4AhHRmp5W6u3t_4XWiImXkuo6-0ceK-vZ6ks/s1600/site.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi17ievEazp3jiCLgDiInIW_XcTT9bb1xjUTxSjzIU0S7qaNv4BBtq_N-NNbiidQiwO8d3iy7k7BV9e5SriMLV2fIMtf9TPVx_voquga_e4AhHRmp5W6u3t_4XWiImXkuo6-0ceK-vZ6ks/s320/site.jpg&quot; /&gt;&lt;/a&gt;
&lt;br&gt;

※追記&lt;br&gt;
アップグレードボタンを押しても、エラーで更新されない時があります。この場合、web2pyフォルダーにある &lt;strong&gt;web2py_src_downloaded.zip&lt;/strong&gt;
ファイルを削除してみてください。前回アップグレード時に使用した更新用ファイルが、削除できないのが原因です。

&lt;p&gt;
しかし元のweb2pyのバージョンが古い場合など、更新が上手く行われない場合があります。その場合は、２番目の方法（b）でアップグレードすることが必要です。

&lt;p&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMkt03DeuMh2rqLfl32W4-CEIP4YXhvlZ0O8YrObmK2jj3CniSQiHx2JwlXeWujRc8k6KSQbQrHLAbKlV0sLQDohdfiVqYIwwpRl66uMWj45Odte2KvUO3P6pfTPcMDx0O8U8uS21ifYI/s1600/test.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMkt03DeuMh2rqLfl32W4-CEIP4YXhvlZ0O8YrObmK2jj3CniSQiHx2JwlXeWujRc8k6KSQbQrHLAbKlV0sLQDohdfiVqYIwwpRl66uMWj45Odte2KvUO3P6pfTPcMDx0O8U8uS21ifYI/s320/test.jpg&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
アプリは別の場所で管理して、applicationsフォルダー下にシンボリック・リンクを貼るだけでも大丈夫です。

&lt;p&gt;
三番目の方法（c）は、GitHub のリポジトリにある web2py デベロッパー版を使用している場合に可能です。以前は GoogleCode で Mercurial  で管理されていましたが、現在は Git で管理されています（昨年末位に変更になりました）。

&lt;h5&gt;アップグレード後の新規アプリケーションの注意点&lt;/h5&gt;

新規アプリは、 welcome アプリをひな形に生成されます。しかしアップグレード後に新規アプリを生成しても、アップグレードが反映されていない時があります。その場合 web2py フォルダーの次のファイルを削除してください。

&lt;p&gt;
&lt;span style=&quot;margin:10px;padding:10px;background-color:lightgray;&quot;&gt;
welcome.w2p
&lt;/span&gt;

&lt;p&gt;
これは welcomeアプリのパッケージなのですが、アップグレード時に何らかの原因で削除されないまま残ると、アップグレードが反映されないということが起こります。新規アプリケーション作成時に wlecome.w2p ファイルがないと、welcomeアプリから自動生成されます。

&lt;h5&gt;アップグレード後の既存アプリケーションの注意点&lt;/h5&gt;

アップグレードしても、アプリ・フォルダにある既存のファイルの変更は行われません。特に web2py 2.10.1 以降は Bootstrap3 に変更になりましたが、web2py をアップグレードしても既存アプリは Bootstrap2 のままという状態になります。

&lt;p&gt;
もし既存のアプリにもアップグレードを反映させたい場合は、アプリ・フォルダー内のファイルを手動で更新していく必要があります。このためアプリの作成時には、将来のアップグレードも考えて、記述方法を考えておく必要があります。例えば、次のようなことを考慮する必要があります。

&lt;ul&gt;
&lt;li&gt;新規アプリ作成時の既存のファイルには、なるべく変更を加えない。モデル・コントローラ・ビューなどは、アプリ用に新しいファイルを生成して記述する。&lt;/li&gt;
&lt;li&gt;既存ファイルに記述する必要がある場合は、コメントを付けるなど変更点が後日わかるようにしておく。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
以上簡単ですが、アップグレードの豆知識を書いておきます。&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/5180728704957902167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/5180728704957902167'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2015/04/web2py.html' title='web2py アップグレード豆知識'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi17ievEazp3jiCLgDiInIW_XcTT9bb1xjUTxSjzIU0S7qaNv4BBtq_N-NNbiidQiwO8d3iy7k7BV9e5SriMLV2fIMtf9TPVx_voquga_e4AhHRmp5W6u3t_4XWiImXkuo6-0ceK-vZ6ks/s72-c/site.jpg" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-415455339605908645</id><published>2015-04-05T11:15:00.001+09:00</published><updated>2023-01-07T00:30:12.094+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>web2py 2.10.1 と SQLEDITABLE</title><content type='html'>&lt;h5&gt;web2py 2.10.1&lt;/h5&gt;

web2pyフレームワークの&lt;strong&gt;2.10.1&lt;/strong&gt;が公開されました。このバージョンから、Bootstrapが２から３に変更になりました。これは、Bootstrap 2.3.2 の公式サポートの終了が予告されているからです。&lt;br&gt;
他にデータベース関連の DAL モジュールが独立して、&lt;strong&gt;pyDAL&lt;/strong&gt; となりました。この関連の変更も反映しています。
リリースされたweb2pyフレームワークは問題があったようで、バージョンは &lt;strong&gt;2.10.3&lt;/strong&gt; まで上がっています。
&lt;p&gt;
今後 pyDAL は、Python3 に対応していくようです。しかし Google App Engine などが Python2 のままなので、今後どうなるかわかりません。
&lt;p&gt;
&lt;a href=&#39;http://www.web2py.com/init/default/download&#39;&gt;web2py ダウンロードページ&lt;/a&gt;

&lt;h5&gt;SQLEDITABLE&lt;/h5&gt;

&lt;a href=&#39;http://docs-hiho.appspot.com/sqleditable/demo/demo.html&#39;&gt;SQLEDITABLE&lt;/a&gt;も Bootstrap3 への対応のため、バージョンアップしました。現在、 &lt;strong&gt;0.20&lt;/strong&gt; になっています。もし Bootstrap2 で使用したい場合は、&lt;strong&gt;0.18&lt;/strong&gt; を使用してください。

&lt;p&gt;
この他、SQLEDITABLEは仮想フィールドにも対応しました。特に自己参照フィールドを利用した場合、結構面白いユーザインターフェースを実現できます。SQLEDITABLEのデモ１４・１５を参考にしてください。

&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#39;http://docs-hiho.appspot.com/sqleditable/demo/demo.html&#39;&gt; SQLEDITABLE デモページ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#39;http://docs-hiho.appspot.com/sqleditable/demo/demo.html#id17&#39;&gt;デモ１４&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#39;http://docs-hiho.appspot.com/sqleditable/demo/demo.html#id18&#39;&gt;デモ１５&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#39;https://github.com/hiho-/SQLEDITABLE/releases&#39;&gt;SQLEDITABLEリリースページ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
※ SQLEDITABLE 0.18 では、virtualfields.append メソッドで追加した仮想フィールドがある場合にエラーが出るバグがあります。これは 0.20 では修正されています。もし 0.18 を使用する場合は仮想フィールドとして、Field.Virtual メソッド（ニュースタイル仮想フィールド）の方を使用してください。
&lt;p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/415455339605908645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/415455339605908645'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2015/04/web2py-2101-sqleditable.html' title='web2py 2.10.1 と SQLEDITABLE'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-5213928143513742142</id><published>2014-07-03T19:44:00.001+09:00</published><updated>2023-01-07T00:32:08.021+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>SQLEDITABLE プラグイン</title><content type='html'>&lt;strong&gt;SQLEDITABLE&lt;/strong&gt;プラグインを公開しました。次のデモページを参照してください。

&lt;p&gt;
&lt;span style=&quot;color:steelblue;font-size:20px;margin-left:50px;&quot;&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/sqleditable/demo/demo.html&#39;&gt;SQLEDITABLE デモ&lt;/a&gt;
&lt;/span&gt;

&lt;p&gt;
リンクをクリックしてください。

&lt;p&gt;
追記 2014/07/28&lt;br&gt;
ドキュメントも作成しました。
&lt;p&gt;
&lt;span style=&quot;color:steelblue;font-size:20px;margin-left:50px;&quot;&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/sqleditable/docs/document.html&#39;&gt;SQLEDITABLE ドキュメント&lt;/a&gt;
&lt;/span&gt;




&lt;p&gt; &lt;br&gt;

&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/5213928143513742142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/5213928143513742142'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2014/07/sqleditable.html' title='SQLEDITABLE プラグイン'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-1739072913299951885</id><published>2014-01-26T09:53:00.000+09:00</published><updated>2014-02-08T12:19:35.842+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>web2py Book 第五版　日本語訳</title><content type='html'>&lt;p&gt;
web2py Book の第五版の日本語訳は、&lt;a href=&#39;http://web2py.com/book#&#39;&gt;本家サイト&lt;/a&gt; の方は公開されているのですが、表示がおかしいなどの問題があります。このため、次のURLで修正版を公開しています。宜しかったら参照してください。

&lt;p&gt;
&lt;span style=&quot;color:steelblue;font-size:20px;&quot;&gt;
&lt;a href=&#39;http://web2py-book.appspot.com/chapter/33&#39;&gt;http://web2py-book.appspot.com/chapter/33&lt;/a&gt;
&lt;/span&gt;

&lt;p&gt;&lt;p&gt;
&lt;br&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/1739072913299951885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/1739072913299951885'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2014/01/web2py-book.html' title='web2py Book 第五版　日本語訳'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-6643777425116042628</id><published>2013-09-24T20:06:00.000+09:00</published><updated>2013-09-25T06:22:41.975+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>web2py 静的アセット管理</title><content type='html'>以前メーリングリストで、web2pyの「静的アセット管理」について書いたことがありますが、このブログでも少し内容を拡張して書いてみます。

&lt;h5&gt;静的アセット管理&lt;/h5&gt;

&lt;p&gt;
静的アセット管理とは、静的ファイルをブラウザのキャッシュで利用する仕組みだ。Django でも同じような機能のコンポーネントがあるようだ。

&lt;p&gt;
具体的には次のように、モデル定義（db.pyなど）に記述する。

&lt;div style=&quot;border: double 3px green; margin: 10px; padding: 10px;&quot;&gt;
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;response.static_version = &amp;#x27;1.1.1&amp;#x27;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;
これによって次のように動作する。

&lt;ol&gt;
&lt;li&gt;静的ファイルのURL変更&lt;/li&gt;
&lt;li&gt;静的ファイルのヘッダ情報の書き換え&lt;/li&gt;
&lt;li&gt;対象の静的ファイルは、response.files に含まれているファイル&lt;/li&gt;
&lt;/ol&gt;

もう少し詳しく説明すると、

&lt;dl&gt;
&lt;dt&gt;1. 静的ファイルのURL変更&lt;/dt&gt;
&lt;dd&gt;
例えば次のような静的ファイルのURLが、

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;http://127.0.0.1:8000/myapp/static/css/web2py.css&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

次のように変更される。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;http://127.0.0.1:8000/myapp/static/_1.1.1/css/web2py.css&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


つまり、response.static_version で設定した値が、&lt;span style=&quot;background-color: #E8E8E8;padding:0 5px;margin:0 5px&quot;&gt;&lt;strong&gt;/_1.1.1&lt;/strong&gt;&lt;/span&gt;のように静的ファイルのURLの一部に含まれるようになる。


&lt;/dd&gt;&lt;br&gt;

&lt;dt&gt;2. 静的ファイルのヘッダ情報の書き換え&lt;/dt&gt;
&lt;dd&gt;
response.static_version の設定がある場合とない場合のヘッダ情報を比べると、次の項目が変更追加されていることがわかる。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;Expires: Thu, 31 Dec 2037 23:59:59 GMT&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Cache-Control: max-age=315360000&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

設定がない場合は、&lt;strong&gt;Expires&lt;/strong&gt; の項目がなく、&lt;strong&gt;Cache-Control&lt;/strong&gt; にも private が設定されている。これらの値が設定されることにより、静的ファイルがブラウザキャッシュから使用されるようになる。またキャッシュの有効期限が Expires の場合は２０３７年まで、Cache-Control は期間を１０年で指定している。

&lt;/dd&gt;&lt;br&gt;


&lt;dt&gt;3. 対象の静的ファイルは、response.files に含まれているファイル&lt;/dt&gt;
&lt;dd&gt;
response.static_version が適用されるファイルは、response.filesに指定したファイルになる。デフォルトでは次の静的ファイルが含まれる。

&lt;ul&gt;
&lt;li&gt;js/jquery.js&lt;/li&gt;
&lt;li&gt;css/calendar.css&lt;/li&gt;
&lt;li&gt;js/calendar.js&lt;/li&gt;
&lt;li&gt;js/web2py.js&lt;/li&gt;
&lt;li&gt;css/web2py.css&lt;/li&gt;
&lt;li&gt;css/bootstrap.min.css&lt;/li&gt;
&lt;li&gt;css/bootstrap-responsive.min.css&lt;/li&gt;
&lt;li&gt;css/web2py_bootstrap.css&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;


&lt;h5&gt;効果と注意点&lt;/h5&gt;

ここでブラウザのキャッシュの中身を見てみよう。

&lt;p&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisuSjFZbCUw6IuoeGcQQOTOoYBQ2Y9FHzros-yDp2r7VsM7DD_bLeMyHGLKs5MFeTgCmjUUrcoSW-xGZCvI6ziGPiCIXUxM_lUxBgT_-__Z_I9mP9WUcFnt_EtnDnt6q7cIFCblbLHKwE/s1600/web2py_static_asset_manegment001.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisuSjFZbCUw6IuoeGcQQOTOoYBQ2Y9FHzros-yDp2r7VsM7DD_bLeMyHGLKs5MFeTgCmjUUrcoSW-xGZCvI6ziGPiCIXUxM_lUxBgT_-__Z_I9mP9WUcFnt_EtnDnt6q7cIFCblbLHKwE/s640/web2py_static_asset_manegment001.jpg&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
静的アセット管理の対象ファイルのキャッシュ期限が、１０年後の２０２３年に指定されていることが確認できる。

&lt;p&gt;
静的アセット管理を設定した場合、ブラウザキャッシュによる効果として、次の二点が考えられる。

&lt;ul&gt;
&lt;li&gt;ネットワーク負荷の削減&lt;/li&gt;
&lt;li&gt;サーバ負荷の削減&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
もちろんブラウザキャッシュを使用するため、対象の静的ファイルが変更された場合など、本来サーバ上のファイルを使用すべきものが、ブラウザキャッシュのファイルを使用してしまう可能性がある。このため対象となる静的ファイルを変更した場合は、response.static_versio を変更する必要がある。例えば次のように変更する。

&lt;div style=&quot;border: double 3px green; margin: 10px; padding: 10px;&quot;&gt;
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;response.static_version = &amp;#x27;1.1.2&amp;#x27;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
これによって静的ファイルのURLに含まれていた &lt;span style=&quot;background-color: #E8E8E8;padding:0 5px;margin:0 5px&quot;&gt;&lt;strong&gt;/_1.1.1&lt;/strong&gt;&lt;/span&gt; が、&lt;span style=&quot;background-color: #E8E8E8;padding:0 5px;margin:0 5px&quot;&gt;&lt;strong&gt;/_1.1.2&lt;/strong&gt;&lt;/span&gt; と変更されるため、新しいファイルとして認識される。

&lt;p&gt;
以後ファイルの変更の度に、response.static_version に指定する番号を、過去の番号と重複しないように変更する必要がある。


&lt;h5&gt;さらなる活用&lt;/h5&gt;

静的アセット管理の仕組みは記述さえすれば、常にブラウザキャッシュを使用するため便利な設定であるが、デフォルトで対象となるファイルは限定されている。画像ファイルなどのキャッシュを利用すれば負荷を大きく削減できるファイルに適用するためには、次のように設定する。

&lt;div style=&quot;border: double 3px green; margin: 10px; padding: 10px;&quot;&gt;
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;URL(&amp;#x27;static&amp;#x27;, (&amp;#x27;_&amp;#x27;+response.static_version+&amp;#x27;/&amp;#x27; \&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;                     if response.static_version else &amp;#x27;&amp;#x27;) +&amp;#x27;images/test.jpg&amp;#x27;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
アプリケーションの static ディレクトリの image/test.jpg ファイルを、静的アセット管理で参照する。この記述を利用したコントローラ関数の例を次に示す。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;go&quot;&gt;def image():&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;   img = IMG(_src=URL(&amp;#x27;static&amp;#x27;, (&amp;#x27;_&amp;#x27;+response.static_version+&amp;#x27;/&amp;#x27; \&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;                        if response.static_version else &amp;#x27;&amp;#x27;) +&amp;#x27;images/test.jpg&amp;#x27;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;   return dict(img=img)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
このコントローラ関数を実行すると、image/test.jpg の画像を画面に表示する。


&lt;h5&gt;Google app engine での注意点&lt;/h5&gt;

&lt;p&gt;
web2py &lt;strong&gt;2.4.7&lt;/strong&gt; 以前のバージョンでは、GAE上での静的アセット管理に対応していない。この場合、&lt;strong&gt;app.yaml&lt;/strong&gt; の次の記述を、

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/(?P&amp;lt;a&amp;gt;.+?)/static/(?P&amp;lt;b&amp;gt;.+)&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;static_files&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;applications/\1/static/\2&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;applications/(.+?)/static/(.+)&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;secure&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;optional&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
次のように変更することが必要だ。

&lt;div style=&quot;border: double 3px green; margin: 10px; padding: 10px;&quot;&gt;
&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/(.+?)/static/_\d.\d.\d\/(.+)&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;static_files&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;applications/\1/static/\2&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;applications/(.+?)/static/(.+)&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;secure&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;optional&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;expiration&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;365d&amp;quot;&lt;/span&gt;

&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/(.+?)/static/(.+)&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;static_files&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;applications/\1/static/\2&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;applications/(.+?)/static/(.+)&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;secure&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;optional&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

expiration でキャッシュ期限を一年で設定している。必要であれば、この値も変更ください。

&lt;p&gt;&lt;br&gt;
静的アセット管理の仕組みを使用すれば、気軽にアプリケーションのチューニングを行えます。結構大規模なサイトでないと効果がハッキリ出ないかもしれませんが、容易に実施できるというのが利点です。








&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/6643777425116042628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/6643777425116042628'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2013/09/web2py_24.html' title='web2py 静的アセット管理'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisuSjFZbCUw6IuoeGcQQOTOoYBQ2Y9FHzros-yDp2r7VsM7DD_bLeMyHGLKs5MFeTgCmjUUrcoSW-xGZCvI6ziGPiCIXUxM_lUxBgT_-__Z_I9mP9WUcFnt_EtnDnt6q7cIFCblbLHKwE/s72-c/web2py_static_asset_manegment001.jpg" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-4045045226664812191</id><published>2013-09-09T23:36:00.001+09:00</published><updated>2023-01-07T00:43:20.724+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>web2py 補足ドキュメントについて ⑤</title><content type='html'>近い内に web2py Book 日本語第５版が公開される予定です。

&lt;p&gt;
&lt;a href=&#39;http://www.web2py.com/books/default/chapter/29/06/the-database-abstraction-layer#&#39;&gt;web2py Book 英語 第５版&lt;/a&gt;&lt;br&gt;
&lt;a href=&#39;http://www.web2py.com/books/default/chapter/33&#39;&gt;web2py Book 日本語 第４版&lt;/a&gt;

&lt;p&gt;
第５版に合わせて、&lt;a href=&#39;http://docs-hiho.appspot.com/index.html&#39;&gt;web2py 捕捉ドキュメント&lt;/a&gt; も改定しました。DALの箇所しか変更していませんが、次のようにページを変更追加しました。

&lt;p&gt;
トピックス
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/topics/function_field/virtual_field.html#virtual-newstyle&#39;&gt;ニュースタイル仮想フィールド&lt;/a&gt; - クラス名が変更になりました
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/topics/function_field/filterin_filterout.html&#39;&gt;fiter_in と filter_out&lt;/a&gt; - 新規追加
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/topics/operation_by_dict.html&#39;&gt;辞書型データを使用したデータ操作&lt;/a&gt; - 新規追加
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/topics/callback_function.html&#39;&gt;コールバック関数&lt;/a&gt; - 新規追加
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/topics/record_versioning.html&#39;&gt;レコードバージョン管理&lt;/a&gt; - 新規追加
&lt;/li&gt;

&lt;/ul&gt;

クラス説明
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_table.html#dal.Table._enable_record_versioning&#39;&gt;Tableクラス _enable_record_versioning&lt;/a&gt; - 新規追加
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_query.html#dal.Query.case&#39;&gt;Queryクラス case&lt;/a&gt; - 新規追加（CASE式が使えるようになりました）
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_query.html#dal.Query.as_dict&#39;&gt;Queryクラス as_dict/as_json/as_xml&lt;/a&gt; - 新規追加
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_expression.html#dal.Expression.regexp&#39;&gt;Expressionクラス regexp&lt;/a&gt; - 新規追加（正規表現検索）
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_expression.html#dal.Expression.avg&#39;&gt;Expressionクラス avg&lt;/a&gt; - 新規追加（平均値取得）
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_expression.html#dal.Expression.abs&#39;&gt;Expressionクラス abs&lt;/a&gt; - 新規追加（絶対値取得）
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_set.html#dal.Set.update_naive&#39;&gt;Setクラス update_naive&lt;/a&gt; - 新規追加（コールバック関数を無視して更新）
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_set.html#dal.Set.nested_select&#39;&gt;Setクラス nested_select&lt;/a&gt; - 新規追加（ネストしたSELECT）
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_rows.html#dal.Rows.xml&#39;&gt;Rowsクラス xml&lt;/a&gt; - 新規追加
&lt;/li&gt;

&lt;li&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_rows.html#dal.Rows.json&#39;&gt;Rowsクラス json&lt;/a&gt; - 新規追加
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
他にも変更・追記した箇所があると思います。宜しかったら参考にしてください。

&lt;p&gt;
※ 以前のサンプルコードで &lt;strong&gt;owner&lt;/strong&gt; フィールドを使っていたものがありましたが、&lt;strong&gt;owner&lt;/strong&gt;がDALの禁止ワードに指定されたので、owner_id に変更しました。
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/4045045226664812191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/4045045226664812191'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2013/09/web2py.html' title='web2py 補足ドキュメントについて ⑤'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-8992487553928684554</id><published>2013-04-19T02:09:00.001+09:00</published><updated>2023-01-07T00:46:21.931+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>web2py でのテスト ③ モジュールでのdoctestの実行方法</title><content type='html'>&lt;p&gt;
かなり久しぶりの投稿です。以前、次のような &lt;strong&gt;doctest&lt;/strong&gt; に関する記事を投稿しました。

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#39;http://todayspython.blogspot.com/2012/07/web2py-doctest.html&#39;&gt;web2py でのテスト ① doctestの使い方&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#39;http://todayspython.blogspot.com/2012/07/web2py-doctest_17.html&#39;&gt;web2py でのテスト ② doctestコードの書き方&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
今回は &lt;strong&gt;モジュール&lt;/strong&gt; での doctest の実行方法について書いてみます。

&lt;h5&gt;モジュールについて&lt;/h5&gt;

&lt;p&gt;
最初に web2py のモジュールについて、簡単に説明します。モジュールは、共通関数などを抜き出し、独立性の高いコードとして設定するものです。
web2py管理画面の「モジュール」というセクションで、モジュールファイルの作成やアップロードが可能になっています。

&lt;p&gt;
&lt;a href=&quot;https://picasaweb.google.com/lh/photo/NzxMBGGd10D83vfDu3-fecsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhw-DFasDpO56Zbo8NZtvc3cojrM8geSIOlF9HGcm9ino5FvHo8sxSnGlNqn0vI6WKA_ugvWMRaMgUbaxjxs3b92jv822XaNhQS5DA18sDWRqBgjoDId1YYxeFfdekY8G93RHW27BXNv8/s400/web2py_test004.jpg&quot; height=&quot;280&quot; width=&quot;400&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;p&gt;
モジュールを利用する場合の注意点を少し書いてみます。

&lt;dl&gt;
&lt;dt&gt;モデル変数の扱い&lt;/dt&gt;
&lt;dd&gt;
モジュールはコントローラやモデルでのコード記述とは違い、モデルで定義した変数にはアクセスできません。このためモジュールで記述する関数やクラスで、
モデル定義の変数（db や auth など）を使用したい場合は、&lt;s&gt;パラメータでこれらの変数を渡してやる&lt;/s&gt; &lt;font color=&quot;red&quot;&gt;current変数に渡してやる&lt;/font&gt; 必要があります（注：記述が間違っていました &lt;a href=&quot;http://www.web2py.com/books/default/chapter/33/04#PythonモジュールからのAPIアクセス&quot;&gt;web2py book モジュールからのAPIアクセスを参照&lt;/a&gt;）。
&lt;/dd&gt; 

&lt;dt&gt;Pythonモジュールの利用&lt;/dt&gt;
&lt;dd&gt;
easy_install や pip などで導入する Python モジュールを、web2py 内に設定し利用することが可能です。この場合は管理画面のモジュールを利用するのでは
無く、web2py ディレクトリの &lt;strong&gt;site-packages&lt;/strong&gt; に設定します。具体的には次のページで設定方法を紹介していますので、
参考にしてください。&lt;br&gt;

&lt;a href=&#39;http://todayspython.blogspot.com/web2py_ac/authentication/methods/openid_gae.html&#39;&gt;Google AppEngine での Python-OpenID モジュールの設定&lt;/a&gt;

&lt;p&gt;
これは本番の Python 環境で、モジュールを追加できない場合などに利用可能です。
&lt;/dd&gt;

&lt;dt&gt;コード開発時に便利な設定&lt;/dt&gt;
&lt;dd&gt;
モジュールは一度インポートされると、モジュールのコード変更しても再度読み込まれることはありません。
しかしこのような動作は、コード開発時には不都合です。
もし次のコードをモデル定義に記述しておけば、モジュールのインポート命令がある度に、コードの変更チェックを行います。
変更がある場合は、モジュールのリロードを行います。

&lt;div class=&quot;highligh&quot; style=&quot;background: #f8f8f8; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;background: #f8f8f8;white-space:pre;box-shadow:none;color:black;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;from&lt;/span&gt; &lt;span style=&quot;color: #0000FF; font-weight: bold&quot;&gt;gluon.custom_import&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;import&lt;/span&gt; track_changes; track_changes(&lt;span style=&quot;color: #008000&quot;&gt;True&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
本番環境ではモジュールのリロードは不要ですので、コードをコメントにします。

&lt;/dd&gt;
&lt;/dl&gt;

&lt;h5&gt;モジュールテストの例&lt;/h5&gt;

&lt;p&gt;
さて本題のモジュールのテストについて、入っていきます。まず &lt;strong&gt;date_calculator.py&lt;/strong&gt; というモジュールファイルを生成し、次のコードを記述します。

&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# coding: utf8&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;gluon&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;last_friday&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;#x27;&amp;#x27;&amp;#x27;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;gt;&amp;gt;&amp;gt; last_friday()    #doctest: +ELLIPSIS&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    datetime.date(...&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;gt;&amp;gt;&amp;gt; last_friday(&amp;#x27;20130101&amp;#x27;)&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    datetime.date(2012, 12, 28)&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;gt;&amp;gt;&amp;gt; last_friday(20130101)&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    Traceback (most recent call last):&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    ...&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    TypeError: must be string, not int&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;gt;&amp;gt;&amp;gt; last_friday(&amp;#x27;2013/01/01&amp;#x27;)    #doctest: +ELLIPSIS&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    Traceback (most recent call last):&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    ...&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    ValueError: ...&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;#x27;&amp;#x27;&amp;#x27;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retrieve_date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weekday&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weeks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;next_monday&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;#x27;&amp;#x27;&amp;#x27;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;gt;&amp;gt;&amp;gt; next_monday()    #doctest: +ELLIPSIS&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    datetime.date(...&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;gt;&amp;gt;&amp;gt; next_monday(&amp;#x27;20130101&amp;#x27;)&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    datetime.date(2013, 1, 7)&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;gt;&amp;gt;&amp;gt; next_monday(20130101)&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    Traceback (most recent call last):&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    ...&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    TypeError: must be string, not int&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;gt;&amp;gt;&amp;gt; next_monday(&amp;#x27;2013/01/01&amp;#x27;)    #doctest: +ELLIPSIS&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    Traceback (most recent call last):&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    ...&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    ValueError: ...&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;#x27;&amp;#x27;&amp;#x27;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retrieve_date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weekday&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;retrieve_date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weekday&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init_date&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;init_date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;init_date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strptime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;%Y%m&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init_date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weekday&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weekday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weekday&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;



&lt;p&gt;
簡単に解説すると、 &lt;strong&gt;last_friday&lt;/strong&gt;　と &lt;strong&gt;next_monday&lt;/strong&gt; の２つの関数があり、それぞれ 指定日の一番最後の金曜日と、次の
月曜日の datetime.date オブジェクトを返します。既に doctest のコードは、この２つの関数には設定されています。

&lt;p&gt;
このコードの dcotest を実行するには、どうしたら良いでしょうか？。というのは web2pyの管理画面にはコントローラにあるようなテストボタンが、モジュールにはありません。また、コマンドラインからも実行できないようです。


&lt;h5&gt;モジュールテストの実行&lt;/h5&gt;

&lt;p&gt;
doctest はモジュールのままでは実行出来ません。このため、テストが実行可能なコントローラにインポートします。

&lt;p&gt;
まず、ダミーのコントローラファイルを作成します。ここでは &lt;strong&gt;test.py&lt;/strong&gt; とし、次のコードを記述します。


&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;1
2
3
4&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;c&quot;&gt;# coding: utf8&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# try something like&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;date_calculator&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last_friday&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;date_calculator&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next_monday&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;/&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;
コードを記述し保存したら、管理画面からテストを実行してみます。

&lt;p&gt;
&lt;a href=&quot;https://picasaweb.google.com/lh/photo/cA18cZnQGqlV4ZD1_exdv8sKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAdAVey8XPw3TtgV9tYFWo8lJ0XOtG9_wrHgkB_Drl8uLde355txXfSDD_6m8pnJBqJv70rT4ebKyd4fzJH_K6wDZyHRvmmNgVYmiH0K-YeoyqZixuQbhqZuiepMG2GL9EVQbpnGfhyphenhyphensY/s400/web2py_test005.jpg&quot; height=&quot;272&quot; width=&quot;400&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;p&gt;
正常に、 doctest を実行したことが確認できました。

&lt;p&gt;
モジュールの doctest ではコントローラにダミーファイルを作成し、モジュールの関数をインポートすることにより実行できるということが、理解して頂けたと思います。&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8992487553928684554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8992487553928684554'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2013/04/web2py-doctes.html' title='web2py でのテスト ③ モジュールでのdoctestの実行方法'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhw-DFasDpO56Zbo8NZtvc3cojrM8geSIOlF9HGcm9ino5FvHo8sxSnGlNqn0vI6WKA_ugvWMRaMgUbaxjxs3b92jv822XaNhQS5DA18sDWRqBgjoDId1YYxeFfdekY8G93RHW27BXNv8/s72-c/web2py_test004.jpg" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-8689193194090981142</id><published>2012-12-03T22:08:00.002+09:00</published><updated>2023-01-07T00:47:10.466+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>web2py を AWS Elastic Beanstalk で動かす設定</title><content type='html'>&lt;p&gt;
web2py を Amazon web services (&lt;strong&gt;AWS&lt;/strong&gt;) の &lt;strong&gt;Elastic Beanstalk&lt;/strong&gt; で動作させるための手順を、ドキュメント化しました。宜しかったら、参考にしてください。

&lt;p&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_deploy/aws_beanstalk/aws_beanstalk.html&#39; style=&#39;font-size:large&#39;&gt;AWS Elastic Beanstalk デプロイ手順&lt;/a&gt;

&lt;p&gt;
↑　↑　↑　リンクをクリックしてください。&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8689193194090981142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8689193194090981142'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2012/12/web2py-aws-elastic-beanstalk.html' title='web2py を AWS Elastic Beanstalk で動かす設定'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-2362086105602383410</id><published>2012-11-12T08:06:00.001+09:00</published><updated>2023-01-07T00:50:39.084+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SyntaxHighlighter"/><title type='text'>syntax2html のバージョンアップ</title><content type='html'>&lt;p&gt;
ソースコード変換サービスの &lt;a href=&#39;http://syntax2html.appspot.com/&#39;&gt;syntax2html&lt;/a&gt; を若干バージョンアップしました。改善点は次の通りです。

&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;インラインCSS機能を強化しました。&lt;/li&gt;
&lt;li&gt;pygments 1.4 から 1.5 に変更しました。これにより、対応するコードは２３５種類になりました。&lt;/li&gt;
&lt;li&gt;ユーザ・インターフェースを改善する共に、多少のバグを修正しました。&lt;/li&gt;
&lt;li&gt;syntax2html サイトへのリンク機能を付け加えました。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
一番大きい改善は、インラインCSS機能の強化です。pygments の吐き出すインラインCSSのコードは、他のCSSコードの影響を全く考慮していませんでした。また行番号をインラインCSSで出力すると、レイアウトが崩れるという問題もありました。このためコードをチェックし、必要なCSSコードをインラインでセットするようにしました。

&lt;p&gt;
次のブログサービスの初期設定で syntax2html が出力したコードの動作を確認しました。


&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://syntax2html.blogspot.com.br/2012/11/syntx2html.html&quot;&gt;Google Blogger － サンプル出力&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://syntax2html.blog.fc2.com/blog-entry-1.html&quot;&gt;FC2 ブログ － サンプル出力&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://synta2html.doorblog.jp/archives/19782731.html&quot;&gt;Livedoor ブログ － サンプル出力&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ameblo.jp/hiho-2/entry-11402379798.html&quot;&gt;Ameba ブログ － サンプル出力&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;reference external&quot; href=&quot;http://syntax2html.seesaa.net/article/301412159.html&quot;&gt;Seesaa ブログ － サンプル出力&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://syntax2html.hatenablog.com/entry/2012/11/15/012157&quot;&gt;はてな ブログ － サンプル出力&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://syntax2html.wordpress.com/2012/11/14/syntax2html-%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E5%87%BA%E5%8A%9B%E4%BE%8B-2/&quot;&gt;wordpress.com － サンプル出力&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;
レイアウトのズレは対症療法的になってしまいますので、まだ不十分だとは思います。

&lt;p&gt;
インラインCSSは、普段はソースコードをブログには載せないが、ブログで公開する必要に迫られた場合に、使用すれば便利だと思います。ブログ側では何も設定は必要ありません（syntax2html が出力したHTMLコードを記事にコピするだけ）。

&lt;p&gt;
syntax2html へのリンク機能は、特に意味がありません。もし表示したくない場合は、「syntax2html へのリンクを表示」のチェックを外すだけです。

&lt;p&gt;
最後にインラインCSSのサンプルを紹介します。

&lt;p&gt;
注意&lt;br&gt;
インラインCSSを使っていますが、このブログでは syntax2html 用に特別なCSSを設定しています。このため、サンプルで表示されている行番号とコードの間の線は、通常のインラインCSSでは表示されません。


&lt;p&gt;
■ AWK のコード（Pygments 1.5 で追加されました）

&lt;table class=&quot;highlightable&quot; style=&quot;background: #000000;&quot;&gt;&lt;tr&gt;&lt;td style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;linenodiv&quot; style=&quot;background: #000000;&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:gray;padding:.5em;line-height: 125%&quot;&gt;1&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot; style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;background: #000000; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:black;background: #000000;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #87ceeb&quot;&gt;/^AWK/&lt;/span&gt; { &lt;span style=&quot;color: #ff0000&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #87ceeb&quot;&gt;&amp;quot;この行は AWK ではじまる行です。&amp;quot;&lt;/span&gt; }
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;



&lt;p&gt;
■ Dart のコード（Pygments 1.5 で追加されました）

&lt;table class=&quot;highlightable&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;tr&gt;&lt;td style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;linenodiv&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:gray;padding:.5em;line-height: 125%&quot;&gt;1
2
3
4
5&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot; style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;background: #f8f8f8; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:black;background: #f8f8f8;padding:.5em; line-height: 125%&quot;&gt;#&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;import&lt;/span&gt;(&lt;span style=&quot;color: #BA2121&quot;&gt;&amp;#x27;dart:html&amp;#x27;&lt;/span&gt;);
&lt;span style=&quot;color: #B00040&quot;&gt;void&lt;/span&gt; main() {
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;var&lt;/span&gt; elem &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; query(&lt;span style=&quot;color: #BA2121&quot;&gt;&amp;#x27;#text&amp;#x27;&lt;/span&gt;);
    elem.text &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;#x27;Hello, Dart!&amp;#x27;&lt;/span&gt;;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;
■ DTD のコード（Pygments 1.5 で追加されました）
&lt;table class=&quot;highlightable&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;tr&gt;&lt;td style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;linenodiv&quot; style=&quot;background: #f8f8f8;&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:gray;padding:.5em;line-height: 125%&quot;&gt;1
2
3
4
5
6&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot; style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;background: #f8f8f8; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:black;background: #f8f8f8;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;&amp;lt;!ELEMENT&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;firstName&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;#PCDATA&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;&amp;lt;!ELEMENT&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;secondName&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;#PCDATA&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;&amp;lt;!ELEMENT&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;info&lt;/span&gt; &lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;ANY&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;&amp;lt;!ELEMENT&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;data&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;firstName&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;secondName&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;?)&lt;/span&gt;&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;&amp;lt;!ELEMENT&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;myDocument&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;)*&lt;/span&gt;&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;&amp;lt;!ATTLIST&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;data&lt;/span&gt; &lt;span style=&quot;color: #BB4444&quot;&gt;age&lt;/span&gt; &lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;CDATA&lt;/span&gt; &lt;span style=&quot;color: #AA22FF; font-weight: bold&quot;&gt;#IMPLIED&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;
■ F# のコード（Pygments 1.5 で追加されました）
&lt;table class=&quot;highlightable&quot; style=&quot;background: #f0f0f0;&quot;&gt;&lt;tr&gt;&lt;td style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;linenodiv&quot; style=&quot;background: #f0f0f0;&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:gray;padding:.5em;line-height: 125%&quot;&gt;1
2
3
4&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot; style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;background: #f0f0f0; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:black;background: #f0f0f0;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #007020; font-weight: bold&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color: #007020; font-weight: bold&quot;&gt;rec&lt;/span&gt; factorial n &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;
    &lt;span style=&quot;color: #007020; font-weight: bold&quot;&gt;match&lt;/span&gt; n &lt;span style=&quot;color: #007020; font-weight: bold&quot;&gt;with&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #40a070&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #40a070&quot;&gt;1&lt;/span&gt;
    &lt;span style=&quot;color: #666666&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;_&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt; n &lt;span style=&quot;color: #666666&quot;&gt;*&lt;/span&gt; factorial &lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;n &lt;span style=&quot;color: #666666&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #40a070&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;
■ Groovy のコード（Pygments 1.5 で追加されました）
&lt;table class=&quot;highlightable&quot; style=&quot;background: #000000;&quot;&gt;&lt;tr&gt;&lt;td style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;linenodiv&quot; style=&quot;background: #000000;&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:gray;padding:.5em;line-height: 125%&quot;&gt;1
2
3
4
5
6
7
8
9&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot; style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;background: #000000; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:black;background: #000000;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #00cd00&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #00cdcd&quot;&gt;Greet&lt;/span&gt; &lt;span style=&quot;color: #3399cc&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #00cd00&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #cccccc&quot;&gt;name&lt;/span&gt;
  &lt;span style=&quot;color: #cccccc&quot;&gt;Greet&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cccccc&quot;&gt;who&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #3399cc&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;color: #cccccc&quot;&gt;name&lt;/span&gt; &lt;span style=&quot;color: #3399cc&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cccccc&quot;&gt;who&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cd00cd&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color: #cccccc&quot;&gt;toUpperCase&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #3399cc&quot;&gt;+&lt;/span&gt;
                      &lt;span style=&quot;color: #cccccc&quot;&gt;who&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cd00cd&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;..-&lt;/span&gt;&lt;span style=&quot;color: #cd00cd&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #3399cc&quot;&gt;}&lt;/span&gt;
  &lt;span style=&quot;color: #00cd00&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #cccccc&quot;&gt;salute&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #3399cc&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;color: #cccccc&quot;&gt;println&lt;/span&gt; &lt;span style=&quot;color: #cd0000&quot;&gt;&amp;quot;Hello $name!&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #3399cc&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #3399cc&quot;&gt;}&lt;/span&gt;

&lt;span style=&quot;color: #cccccc&quot;&gt;g&lt;/span&gt; &lt;span style=&quot;color: #3399cc&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdcd00&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #cccccc&quot;&gt;Greet&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cd0000&quot;&gt;&amp;#x27;world&amp;#x27;&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #000080&quot;&gt;// ???????????????????????????&lt;/span&gt;
&lt;span style=&quot;color: #cccccc&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cccccc&quot;&gt;salute&lt;/span&gt;&lt;span style=&quot;color: #3399cc&quot;&gt;()&lt;/span&gt;             &lt;span style=&quot;color: #000080&quot;&gt;// &amp;quot;Hello World!&amp;quot; ?????????&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;
■ JSON のコード（Pygments 1.5 で追加されました）
&lt;table class=&quot;highlightable&quot; style=&quot;background: #111111;&quot;&gt;&lt;tr&gt;&lt;td style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;linenodiv&quot; style=&quot;background: #111111;&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:gray;padding:.5em;line-height: 125%&quot;&gt;1&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot; style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;background: #111111; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:black;background: #111111;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #ffffff&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #fb660a; font-weight: bold&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #ffffff&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #0086d2&quot;&gt;&amp;quot;John Smith&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #ffffff&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fb660a; font-weight: bold&quot;&gt;&amp;quot;age&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #ffffff&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #0086f7; font-weight: bold&quot;&gt;33&lt;/span&gt;&lt;span style=&quot;color: #ffffff&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;
■ MoonScript のコード（Pygments 1.5 で追加されました）

&lt;table class=&quot;highlightable&quot; style=&quot;background: #ffffff;&quot;&gt;&lt;tr&gt;&lt;td style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;linenodiv&quot; style=&quot;background: #ffffff;&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:gray;padding:.5em;line-height: 125%&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot; style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;background: #ffffff; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:black;background: #ffffff;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #208090; font-weight: bold&quot;&gt;export&lt;/span&gt; my_func
x &lt;span style=&quot;color: #303030&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6060f0; font-weight: bold&quot;&gt;2323&lt;/span&gt;

collection &lt;span style=&quot;color: #303030&quot;&gt;=&lt;/span&gt;
  &lt;span style=&quot;color: #003060&quot;&gt;height:&lt;/span&gt; &lt;span style=&quot;color: #6060f0; font-weight: bold&quot;&gt;32434&lt;/span&gt;
  &lt;span style=&quot;color: #003060&quot;&gt;hats:&lt;/span&gt; &lt;span style=&quot;color: #6060f0; font-weight: bold&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;background-color: #e0e0ff&quot;&gt;&amp;quot;tophat&amp;quot;&lt;/span&gt;, &lt;span style=&quot;background-color: #e0e0ff&quot;&gt;&amp;quot;bball&amp;quot;&lt;/span&gt;, &lt;span style=&quot;background-color: #e0e0ff&quot;&gt;&amp;quot;bowler&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #6060f0; font-weight: bold&quot;&gt;}&lt;/span&gt;

my_func &lt;span style=&quot;color: #303030&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6060f0; font-weight: bold&quot;&gt;(&lt;/span&gt;a&lt;span style=&quot;color: #6060f0; font-weight: bold&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #50e0d0; font-weight: bold&quot;&gt;-&amp;gt;&lt;/span&gt; x &lt;span style=&quot;color: #303030&quot;&gt;+&lt;/span&gt; a

&lt;span style=&quot;color: #007020&quot;&gt;print&lt;/span&gt; my_func &lt;span style=&quot;color: #6060f0; font-weight: bold&quot;&gt;100&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
■ PostgreSQL のコード（Pygments 1.5 で追加されました）
&lt;table class=&quot;highlightable&quot; style=&quot;background: #ffffff;&quot;&gt;&lt;tr&gt;&lt;td style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;linenodiv&quot; style=&quot;background: #ffffff;&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:gray;padding:.5em;line-height: 125%&quot;&gt;1
2
3
4&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot; style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;background: #ffffff; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:black;background: #ffffff;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;FUNCTION&lt;/span&gt; square_root(&lt;span style=&quot;color: #007020&quot;&gt;double precision&lt;/span&gt;) &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;RETURNS&lt;/span&gt; &lt;span style=&quot;color: #007020&quot;&gt;double precision&lt;/span&gt;
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;AS&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;#x27;dsqrt&amp;#x27;&lt;/span&gt;
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;LANGUAGE&lt;/span&gt; &lt;span style=&quot;color: #007020&quot;&gt;internal&lt;/span&gt;
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;STRICT&lt;/span&gt;;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;



&lt;p&gt;
■ PowerShell のコード（Pygments 1.5 で追加されました）
&lt;table class=&quot;highlightable&quot; style=&quot;background: #272822;&quot;&gt;&lt;tr&gt;&lt;td style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;linenodiv&quot; style=&quot;background: #272822;&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:gray;padding:.5em;line-height: 125%&quot;&gt;1
2
3&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot; style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;background: #272822; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:black;background: #272822;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #f8f8f2&quot;&gt;PS&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #f8f8f2&quot;&gt;$rssUrl&lt;/span&gt; &lt;span style=&quot;color: #f8f8f2&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #e6db74&quot;&gt;&amp;quot;http://blogs.msdn.com/powershell/rss.aspx&amp;quot;&lt;/span&gt;
&lt;span style=&quot;color: #f8f8f2&quot;&gt;PS&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #f8f8f2&quot;&gt;$blog&lt;/span&gt; &lt;span style=&quot;color: #f8f8f2&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #66d9ef&quot;&gt;[xml]&lt;/span&gt;&lt;span style=&quot;color: #f8f8f2&quot;&gt;(New-Object&lt;/span&gt; &lt;span style=&quot;color: #f8f8f2&quot;&gt;System.Net.WebClient).DownloadString($rssUrl)&lt;/span&gt;
&lt;span style=&quot;color: #f8f8f2&quot;&gt;PS&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #f8f8f2&quot;&gt;$blog.rss.channel.item&lt;/span&gt; &lt;span style=&quot;color: #f8f8f2&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #f8f8f2&quot;&gt;Select&lt;/span&gt; &lt;span style=&quot;color: #f8f8f2&quot;&gt;title&lt;/span&gt; &lt;span style=&quot;color: #f8f8f2&quot;&gt;-first&lt;/span&gt; &lt;span style=&quot;color: #f8f8f2&quot;&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;
■ Scilab のコード（Pygments 1.5 で追加されました）

&lt;table class=&quot;highlightable&quot; style=&quot;background: #ffffff;&quot;&gt;&lt;tr&gt;&lt;td style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;linenodiv&quot; style=&quot;background: #ffffff;&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:gray;padding:.5em;line-height: 125%&quot;&gt;1
2
3
4
5
6&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot; style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;background: #ffffff; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:black;background: #ffffff;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb&quot;&gt; &lt;/span&gt;[x]=&lt;span style=&quot;color: #990000; font-weight: bold&quot;&gt;fact&lt;/span&gt;(k)&lt;span style=&quot;color: #bbbbbb&quot;&gt;&lt;/span&gt;
&lt;span style=&quot;color: #bbbbbb&quot;&gt;  &lt;/span&gt;k=&lt;span style=&quot;color: #999999&quot;&gt;int&lt;/span&gt;(k)
  &lt;span style=&quot;font-weight: bold&quot;&gt;if&lt;/span&gt; k&lt;span style=&quot;font-weight: bold&quot;&gt;&amp;lt;&lt;/span&gt;1 &lt;span style=&quot;color: #999999&quot;&gt;then&lt;/span&gt; k=1,&lt;span style=&quot;font-weight: bold&quot;&gt;end&lt;/span&gt;
  x=1;
  &lt;span style=&quot;font-weight: bold&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #008080&quot;&gt;j&lt;/span&gt;=1:k,x=x&lt;span style=&quot;font-weight: bold&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #008080&quot;&gt;j&lt;/span&gt;;&lt;span style=&quot;font-weight: bold&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;font-weight: bold&quot;&gt;endfunction&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;
■ SystemVerilog のコード（Pygments 1.5 で追加されました）


&lt;table class=&quot;highlightable&quot; style=&quot;background: #ffffff;&quot;&gt;&lt;tr&gt;&lt;td style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;linenodiv&quot; style=&quot;background: #ffffff;&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:gray;padding:.5em;line-height: 125%&quot;&gt;1
2
3
4
5&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot; style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;background: #ffffff; overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;border:none;margin:0;font-size:14px;font-family:monospace;font-style:normal;vertical-align:top;color:black;background: #ffffff;padding:.5em; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #000080; font-weight: bold&quot;&gt;typedef&lt;/span&gt; &lt;span style=&quot;color: #000080; font-weight: bold&quot;&gt;enum&lt;/span&gt; &lt;span style=&quot;color: #000080; font-weight: bold&quot;&gt;reg&lt;/span&gt; [&lt;span style=&quot;color: #0000FF&quot;&gt;2&lt;/span&gt;:&lt;span style=&quot;color: #0000FF&quot;&gt;0&lt;/span&gt;] {
   RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW
} color_t;

color_t   my_color = GREEN;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;&lt;br&gt;
syntax2html へは、こちらのリンクをクリックしてください　→  &lt;a href=&quot;http://syntax2html.appspot.com&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray;font-size:30px;&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue;font-size:30px;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray;font-size:30px;&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;

&lt;p&gt;&lt;br&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/2362086105602383410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/2362086105602383410'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2012/11/syntax2html.html' title='syntax2html のバージョンアップ'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-5676731694893967959</id><published>2012-11-02T03:02:00.001+09:00</published><updated>2023-01-07T00:53:31.821+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>web2py SQLFORM あれこれ ⑥ SQLTALBLEの利用</title><content type='html'>&lt;p&gt;

&lt;a href=&#39;http://todayspython.blogspot.com/2012/10/web2py-sqlform-sqlformgrid.html&#39;&gt;SQLFORM.grid とカスタマイズ１&lt;/a&gt; と &lt;a href=&#39;http://todayspython.blogspot.com/2012/10/web2py-sqlform-sqlformgrid_18.html&#39;&gt;SQLFORM.grid とカスタマイズ２&lt;/a&gt; で、&lt;strong&gt;SQLFORM.grid&lt;/strong&gt; を説明しました。SQLFORM.grid はそれだけで、テーブルの一覧表示やレコードの作成・表示・修正・削除が可能な、非常に便利な機能です。しかしカスタマイズという観点からは、できることは限定されます。
このため今回は &lt;strong&gt;SQLTABLE&lt;/strong&gt; を使用し、もう少し柔軟なカスタマイズを試してみます。

&lt;h5&gt;SQLTABLE で仮想フィールドを利用する場合の注意点&lt;/h5&gt;

&lt;p&gt;
SQLTABLE と SQLFORMの連携について考えてみるが、SQLTABLE 自体に関しては、&lt;a href=&#39;http://todayspython.blogspot.com/web2py_dal/others/sqltable.html&#39;&gt;こちら&lt;/a&gt; を読んで欲しい。今回、SQLTABLE では &lt;a href=&#39;http://todayspython.blogspot.com/web2py_dal/topics/function_field/virtual_field.html#sqltable&#39;&gt;仮想フィールド&lt;/a&gt;
 を利用するが、web2pyのバージョンに関する次の注意点がある。

&lt;p&gt;
&lt;div style=&quot;border: double 3px green; margin: 10px; padding: 10px;&quot;&gt;
&lt;strong&gt;&lt;u&gt;SQLTABLE で仮想フィールドを利用する場合の注意点&lt;/u&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;仮想フィールドは、web2py ver. &lt;strong&gt;2.0.0&lt;/strong&gt; ～ &lt;strong&gt;2.2.1&lt;/strong&gt; では利用できません（バグのため）。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#39;http://todayspython.blogspot.com/web2py_dal/topics/function_field/virtual_field.html#virtual-newstyle&#39;&gt;ニュースタイル仮想フィールド&lt;/a&gt; は、 ver.1.x.x を含む、web2py &lt;strong&gt;ver.2.2.1&lt;/strong&gt; 以前では利用できません（未対応だったため）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;
これはあくまでも、&lt;strong&gt;仮想フィールドを SQLTABLE で利用する&lt;/strong&gt; 場合の注意点だ。現在の最新は 2.2.1 だが、 2.2.1 を含めて 2.x.x 系では仮想フィールドを利用できない。ニュースタイルは、2.x.x 及び 1.x.x でも利用できない。

&lt;p&gt;
記事執筆時点で利用可能なのは、&lt;strong&gt;1.99.7&lt;/strong&gt; などの 1.x.x 系の過去のバージョンと、ニュースタイルも含めたら、&lt;strong&gt;trunk&lt;/strong&gt; バージョンのみとなる。もし今現在、trunk バージョンを利用している場合、最新に更新して欲しい。

&lt;p&gt;
参考：&lt;a href=&#39;http://www.web2py.com/examples/default/download&#39;&gt;web2py download&lt;/a&gt;


&lt;h5&gt;SQLTABLE と SQLFORM の連携（仮想フィールド利用）&lt;/h5&gt;


&lt;p&gt;
SQLFORM に関しては、&lt;a href=&#39;http://todayspython.blogspot.com/2012/09/web2py-sqlform.html&#39;&gt;SQLFORM基本&lt;/a&gt; 及び &lt;a href=&#39;http://todayspython.blogspot.com/2012/09/web2py-sqlform-sqlform.html&#39;&gt;SQLFORMカスタマイズ&lt;/a&gt; で説明をした。記事のコードでは URLパラメータでレコードIDを渡し、該当するIDのレコードが存在する場合は編集・削除が、存在しない場合は新規作成を行う。今回は &lt;a href=&#39;http://todayspython.blogspot.com/2012/09/web2py-sqlform-sqlform.html&#39;&gt;SQLFORMカスタマイズ&lt;/a&gt; に紹介したコードと共に使用可能な、 SQLTABLE のコードを作成する。

&lt;p&gt;
まず、次の SQLTABLE を使ったコードを見て欲しい。

&lt;p&gt;

&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@auth.requires_login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;virtual_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;edit_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; 
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;default&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;download&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IMG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;_href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                    &lt;span class=&quot;n&quot;&gt;user_signature&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            
        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;edit_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_signature&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;icon-pencil&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                     &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;Edit&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;btn&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setvirtualfields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;virtual_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/span&gt;    
&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;image.edit_image&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.category&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;               &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.edit_link&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;image.edit_image&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;Name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
               &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.category&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;Category&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
               &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.edit_link&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;class&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;row_buttons&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;label&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                &lt;span class=&quot;s&quot;&gt;&amp;#x27;width&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;60%&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;selected&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                &lt;span class=&quot;s&quot;&gt;&amp;#x27;truncate&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;add_link&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;icon-plus&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;Add&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;btn&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                 &lt;span class=&quot;n&quot;&gt;_href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_signature&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DIV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SQLTABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;                            &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;web2py_grid&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
このコードでは、Virutal_image クラス定義（２行目）で仮想フィールドの定義を行なっている。さらに、&lt;strong&gt;&lt;a href=&#39;http://todayspython.blogspot.com/web2py_dal/topics/function_field/virtual_field.html#setvirtualfields&#39;&gt;setvirtualfields&lt;/a&gt;&lt;/strong&gt; メソッドで、Rowsオブジェクトに対しての仮想フィールドを設定する（１８行目）。最後に、これらの仮想フィールドを含めた、SQLTABLE オブジェクトを生成している（２９行目）。

&lt;p&gt;
また、SQLTABLE で仮想フィールドを表示する場合に、仮想フィールドを &lt;strong&gt;columns&lt;/strong&gt; パラメータに指定することを忘れてはいけない（２０・２１・２９行目）。columnsパラメターには表示するフィールドを指定するのだが、このパラメータに指定した順にフィールドが表示される事にもなる。

&lt;p&gt;
コードを実行すると、次の画面が表示される。&lt;br&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/neiKiBIp_VEG7wLG3U7yissKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjLMvNP0hQ8SyykIFGJTH88pZRbcCT9UDl0lBBcqfVxXUH2kabbGyFjMQoU8h-cpg5B7703Xmisijs_xYYNJJW9FnM6XNBjyEk2AnA-vB00zPyY6kquDliNOOCG2HctTyGPQHu5GCBjg8/s400/web2py_SQLFORM_028.jpg&quot; height=&quot;305&quot; width=&quot;400&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;p&gt;
画面イメージでは仮想フィールドで定義した、画像及び編集ボタンが追加されている。画像及び編集ボタンは、&lt;strong&gt;href&lt;/strong&gt;属性に image 関数が、URL変数にはレコードのid値が設定されている。このため、クリックすると SQLFORMの編集画面に遷移する。

&lt;p&gt;
今回のコードでは、&lt;a href=&#39;http://twitter.github.com/bootstrap/&#39;&gt;Twitter Bootstrap&lt;/a&gt;を利用している。Bootstrapの詳細は、&lt;a href=&#39;http://todayspython.blogspot.com/2012/10/web2py-sqlform-twitter-bootstrap.html&#39;&gt;Twitter Bootstrap の利用&lt;/a&gt; を参照して欲しい。また画面は、SQLFORM.grid のデザインに合わせるため、&lt;strong&gt;web2py_grid&lt;/strong&gt; クラスを指定している。もし Bootstrap のテーブルデザインにしたい場合、例えば次のように、web2py_gridの代わりにクラスに指定する。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;striped&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bordered&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;
すると画面は次のようなイメージになる。&lt;br&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/2sx_v0tQitzk_pYYfZpPCcsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoUoNZ2mn1ostU7Mk2sIw-TMFN7OzZj8uB1EjvT1wpuwpjbLTEOl4gO1YXdp46Da4yagRSXMBspYYY_8FWlIPp32a4S-U8opowrJnDMbE67qrtrSKr7fOo6aw-YPXDIfjMLHNcVouyY6Q/s400/web2py_SQLFORM_029.jpg&quot; height=&quot;397&quot; width=&quot;400&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;


&lt;h5&gt;SQLTABLE と SQLFORM の連携（ニュースタイル仮想フィールド利用）&lt;/h5&gt;

&lt;p&gt;
同様に、&lt;a href=&#39;http://todayspython.blogspot.com/web2py_dal/topics/function_field/virtual_field.html#virtual-newstyle&#39;&gt;ニュースタイル仮想フィールド&lt;/a&gt; でコードを書いてみる。


&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@auth.requires_login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;edit_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;default&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;download&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IMG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_signature&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;edit_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_signature&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;icon-pencil&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                 &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;Edit&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;btn&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;edit_image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Virtual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;edit_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; 
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;edit_link&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Virtual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;edit_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; 
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;image.edit_image&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.category&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
               &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.edit_link&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;image.edit_image&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;Name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
               &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.category&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;Category&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
               &lt;span class=&quot;s&quot;&gt;&amp;#x27;image.edit_link&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;class&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;row_buttons&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;label&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
               &lt;span class=&quot;s&quot;&gt;&amp;#x27;width&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;60%&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;selected&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;truncate&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;add_link&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;icon-plus&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;Add&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;btn&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                 &lt;span class=&quot;n&quot;&gt;_href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_signature&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DIV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SQLTABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;                                &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;web2py_grid&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
オールドスタイルの仮想フィールドとほぼ同じコードだが、１６・１７行目でニュースタイルで設定している。

&lt;h5&gt;SQLFORM のコード&lt;/h5&gt;

&lt;p&gt;
新規作成・編集・削除を行う SQLFORM のコードは、&lt;a href=&#39;http://todayspython.blogspot.com/2012/09/web2py-sqlform-sqlform.html&#39;&gt;SQLFORMカスタマイズ&lt;/a&gt; ／  &lt;a href=&#39;http://todayspython.blogspot.com/2012/10/web2py-sqlform-twitter-bootstrap.html&#39;&gt;Twitter Bootstrap の利用&lt;/a&gt; で紹介したコードで良いのだが、登録に成功した場合と、キャンセルボタンを押した時のリダイレクト先が設定されていなかった。これらを設定すると、次のコードになる。

&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;check_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;file_delete&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;__delete&amp;#x27;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;file&amp;#x27;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;url&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; 
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;must enter a url&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;on&amp;#x27;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; \
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; 
                 &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;must select a file&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;
            
    &lt;span class=&quot;n&quot;&gt;onchange_js&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;jQuery.noConflict();&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;                if(jQuery(&amp;#x27;#url&amp;#x27;).attr(&amp;#x27;checked&amp;#x27;)){&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;                    jQuery(&amp;#x27;#image_url__row&amp;#x27;).show();&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;                    jQuery(&amp;#x27;#image_file__row&amp;#x27;).fadeOut();}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;                else {&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;                    jQuery(&amp;#x27;#image_file__row&amp;#x27;).show();&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;                    jQuery(&amp;#x27;#image_url__row&amp;#x27;).fadeOut();}&amp;quot;&lt;/span&gt;    
    &lt;span class=&quot;n&quot;&gt;ready_js&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;jQuery(document).ready(function(){&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onchange_js&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;;});&amp;quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;checked&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;checked&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;Image&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;:&amp;#x27;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;radio&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INPUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;radio&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;url_file&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;url&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;_checked&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;checked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;url&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_onchange&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;onchange_js&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;LABEL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;url&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_for&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;url&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27; &amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;INPUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;radio&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;url_file&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;file&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;_checked&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;checked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;file&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_onchange&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;onchange_js&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;LABEL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;file&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_for&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;file&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;margin:0;padding:4px 0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
            
    &lt;span class=&quot;n&quot;&gt;extra_element&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LABEL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;w2p_fl&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                    &lt;span class=&quot;n&quot;&gt;TD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;radio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;w2p_fw&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;TD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;w2p_fc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;url_file__row&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;submit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BUTTON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;icon-ok icon-white&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                      &lt;span class=&quot;n&quot;&gt;_style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;margin-right: 5px;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;OK&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;submit&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;btn btn-primary&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cancel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BUTTON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;icon-remove&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;margin-right: 5px;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;Cancel&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;reset&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;btn&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;                     &lt;span class=&quot;n&quot;&gt;_onclick&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#x27;location.href=&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;#x27;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;table&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;/span&gt;                     &lt;span class=&quot;n&quot;&gt;_style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;margin-left:10px&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SQLFORM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                   &lt;span class=&quot;n&quot;&gt;buttons&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cancel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                   &lt;span class=&quot;n&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;default&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;download&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;onvalidation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;check_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;table&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DIV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SCRIPT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ready_js&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;text/javascript&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;image_url&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#x27;_placeholder&amp;#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
                                            &lt;span class=&quot;s&quot;&gt;&amp;#x27;http://www.example.com&amp;#x27;&lt;/span&gt;
   
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;border:none;&quot;&gt;&lt;/td&gt;&lt;td style=&quot;border:none;text-align:right;&quot;&gt;&lt;a href=&quot;/ja&quot;&gt;&lt;b&gt;&lt;span style=&quot;color:dimgray&quot;&gt;syntax&lt;/span&gt;&lt;span style=&quot;color:steelblue&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:dimgray&quot;&gt;html&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
登録が成功した場合のリダイレクト先は、processメソッドの &lt;strong&gt;next&lt;/strong&gt; パラメータにセットする（５６行目）。キャンセルボタンを押した場合のリダイレクト先は、BUTTONタグの &lt;strong&gt;onclick&lt;/strong&gt; 属性にセットする（４９行目）。

&lt;p&gt;
実行した場合の画面イメージは次のようになる。

&lt;table&gt;&lt;tr&gt;&lt;th&gt;新規登録&lt;/th&gt;&lt;th&gt;編集・削除&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;vertical-align:top&quot;&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/cpmAIXvQqMHV_ZQqGICeXcsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghDayjflR68z46CH3ufOZCoE0TVLZfxfa6sqKNExjw4p0VUYg1xuneeQQ4z6SQhIaw1jlGdg6_WNTottbHxHpYIHQtN8WsN7cCnZUx_njddXjbfbVQF8rnqmSB9pRkpJSe0I9wSTyZ9Kg/s288/web2py_SQLFORM_030.jpg&quot; height=&quot;178&quot; width=&quot;288&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;/td&gt;&lt;td style=&quot;vertical-align:top&quot;&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/Wi3jkJgfhjSv6rvHOHRhSMsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIdwuRAFAl3Y8jX3jy5JqAWxHZhiLJhSTmd1SkziZHb_tUghjbGBvdRmkYQgGL2c-XehNlOS8WXZeItASmH3xkOIj_S3tCQIwqhGsXer77vndT4UHFp0wmTwwONiycL-4l4CVc2XNcyk4/s288/web2py_SQLFORM_031.jpg&quot; height=&quot;260&quot; width=&quot;288&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;h5&gt;注意点など&lt;/h5&gt;

&lt;p&gt;
SQLTABLE と SQLFORM の連携は、&lt;strong&gt;SQLFORM.grid&lt;/strong&gt; を使用する場合に比べて自由度が高い。しかし SQLFORM.grid が持っていた次の機能は、別途コードを記述する必要がある。

&lt;ul&gt;
&lt;li&gt;検索&lt;/li&gt;
&lt;li&gt;ソート&lt;/li&gt;
&lt;li&gt;ページネーション（ページ割り）&lt;/li&gt;
&lt;li&gt;CSVなどへのエクスポート&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
また SQLTABLE には、&lt;a href=&#39;http://todayspython.blogspot.com/2012/10/web2py-sqlform-sqlformgrid_18.html&#39;&gt;SQLFORM.grid とカスタマイズ２&lt;/a&gt; で説明した SQLFORM.grid の link パラメータによく似た、&lt;strong&gt;extracolumns&lt;/strong&gt; パラメータが存在する。extracolumns は自分で定義したフィールドを SQLTABLE に追加できる機能だが、仮想フィールドを使う場合に比べて自由度が落ちる。このため SQLTABLE を使う場合は、今回の記事のように仮想フィールドを使用した方が何かと便利だと思う。

&lt;p&gt;&lt;/br&gt;

今回の記事はこれで終わりです。「SQLFORM あれこれ」のシリーズも、ほぼ終わりです。最後に次回付録的に、SQLTABLE に検索機能を付け加える例を紹介してみたいと思います。&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/5676731694893967959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/5676731694893967959'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2012/11/web2py-sqlform-sqltalble.html' title='web2py SQLFORM あれこれ ⑥ SQLTALBLEの利用'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjLMvNP0hQ8SyykIFGJTH88pZRbcCT9UDl0lBBcqfVxXUH2kabbGyFjMQoU8h-cpg5B7703Xmisijs_xYYNJJW9FnM6XNBjyEk2AnA-vB00zPyY6kquDliNOOCG2HctTyGPQHu5GCBjg8/s72-c/web2py_SQLFORM_028.jpg" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-7188867030168733288</id><published>2012-10-18T00:05:00.001+09:00</published><updated>2023-01-07T00:55:42.296+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>web2py SQLFORM あれこれ ⑤　SQLFORM.grid とカスタマイズ２</title><content type='html'>&lt;p&gt;
&lt;a href=&#39;http://todayspython.blogspot.com/2012/10/web2py-sqlform-sqlformgrid.html&#39;&gt;SQLFORM あれこれ ④&lt;/a&gt; の続きです。今回も SQLFORM.grid を使ったカスタマイズを説明します。

&lt;h5&gt;SQLFORM.grid のカスタマイズ（一覧表示）&lt;/h5&gt;

&lt;p&gt;
前回記事で、SQLFORM.grid の一覧表示画面を紹介した。

&lt;p&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/x-6wxnCAD12PX-5kn42e5MsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvHk_t-VyMpofSkdpmbSq0luqQMu3OrajjKz2Y1Bx1xEZBwUyERm3dS5ic2qf71YG8CM5LzWmW41ZCuhSa1m2rjpJN9cSTDaELpik8HfPjn12aJrlhaBYBx_WQM8SaLL0Bvho28VxjrYk/s400/web2py_SQLFORM_014.jpg&quot; height=&quot;217&quot; width=&quot;400&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;p&gt;
一覧画面のカスタマイズ用に使用可能なパラメータが、いくつか存在する。

&lt;p&gt;
表示項目を指定したり、項目の並び順を変えるカスタマイズでは、&lt;strong&gt;fields&lt;/strong&gt; パラメータを使用する。項目のフィールド名を変更する場合は &lt;strong&gt;headers&lt;/strong&gt; パラメータを指定する。サンプルコードは次のようになる。


&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@auth.requires_login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;manage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;fields&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image.name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;image.category&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Category&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SQLFORM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;download&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;                        &lt;span class=&quot;n&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
コードを実行すると、次の画面イメージが表示される。

&lt;p&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/MFTgKbDRQWN9FdK0tpnRdMsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipnVuC_9R5keLJ8UsWYEzGXS7avCplC0jadMvMvQKjLVKn0iZruGqb3Sa8PRs_z3jV7uY-okmodrSQxGVnf8tN-sXwp-HqIRk6VYHK7ccpXnWCIm1OhSgeExniCuLLKBEdl2rYJcN0AU0/s400/web2py_SQLFORM_020.jpg&quot; height=&quot;230&quot; width=&quot;400&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;p&gt;
少し説明すると、&lt;strong&gt;fields&lt;/strong&gt; には、表示する Fieldオブジェクトを指定する。これはリスト値で、指定順に表示される。&lt;br&gt;
&lt;strong&gt;headers&lt;/strong&gt; は、辞書値でフィールドと名前を指定する。ここでは翻訳オブジェクトである &lt;strong&gt;T&lt;/strong&gt; を使って、名前を指定している。
この他、&lt;strong&gt;csv&lt;/strong&gt; パラメータも指定しているが、これは CSVエクスポートを無効にしている。

&lt;p&gt;
ここまでは普通の設定だ。もう少し難しいことを試してみよう。画像データがあるため、画像を表示するカスタマイズを試してみる。

&lt;p&gt;
テーブルに存在しないフィールドを表示するには、&lt;strong&gt;links&lt;/strong&gt; パラメータを使用する。もともと links はレコードと関連するリンクを表示するためにあるようだが、無名関数（lambda）も使用可能なため、画像表示にも利用可能だ。links は、次のようにリスト値で指定する。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;n&quot;&gt;links&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;download&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                            &lt;span class=&quot;n&quot;&gt;_width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;
links で無名関数を指定した場合、パラメータとしてレコード一覧の Row オブジェクトをが渡される。このためサンプルコードでは、url に値がある場合は src 属性に urlを指定したIMGタグを、urlに値がない場合は src 属性に file を指定する。links はリスト値のため、複数の定義フィールドを指定することも可能だ。

&lt;p&gt;
また links でフィールドを追加する時に、タイトルを付加することも可能だ。その場合、辞書値で &lt;strong&gt;header&lt;/strong&gt; と &lt;strong&gt;body&lt;/strong&gt; を指定し、header にはタイトル、body にはフィールド定義を指定する。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;n&quot;&gt;links&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;header&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
        &lt;span class=&quot;s&quot;&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
         &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;download&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                             &lt;span class=&quot;n&quot;&gt;_width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
&lt;strong&gt;links&lt;/strong&gt; パラメータを指定したコードを実行すると、次の画面イメージになる。

&lt;p&gt;
&lt;a href=&quot;https://picasaweb.google.com/lh/photo/tA5u878e8QG3W1-64w5a0csKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8wcn6CXsTT1xtYXuqlMl0y0niM1t-omjHArLTk-FxOeLwN4jeo815FT5uw405h_PvmIJgAwzMvNlz0IArF8frzarBHRIIbhrITcOvtpnCMM6s2hxzKJ0fBN8jQeaEEwaEQzz6dVRYPjk/s400/web2py_SQLFORM_021.jpg&quot; height=&quot;177&quot; width=&quot;400&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;p&gt;
ここで注意して欲しいのは画面で、url と file フィールドも表示していることである。これは links に指定する無名関数のパラメータには、レコード一覧の Rowオブジェクトが使われるためである。つまり、無名関数で url と file フィールドを利用するために、レコード一覧に url と file が含まれている必要がある。

&lt;p&gt;
しかし無名関数に使用するといっても、一覧表示に url と file フィールドは不要だ。このため SQLFORM.grid の定義の前に、Fieldオブジェクトの &lt;strong&gt;readable&lt;/strong&gt; 属性を False に指定する。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
これによって一覧から、url と file フィールドを隠すことが可能になる。しかし、この設定で詳細表示（View）画面を表示させると、一覧と同様に url と file フィールドも表示されない。このため、&lt;strong&gt;ignore_rw&lt;/strong&gt; パラメータを True に設定し、詳細画面では表示するように変更する。 

&lt;p&gt;
以上まとめると、次のサンプルコードになる。


&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@auth.requires_login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;manage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;fields&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image.name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;image.category&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Category&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;links&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;header&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
            &lt;span class=&quot;s&quot;&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                   &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
             &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;download&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                          &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                                 &lt;span class=&quot;n&quot;&gt;_width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}]&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SQLFORM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;download&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;links&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;links&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignore_rw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
コードを実行すると画面イメージは、次のようになる。

&lt;p&gt;
&lt;a href=&quot;https://picasaweb.google.com/lh/photo/vpgqgm3nLR6Bi2zdCcSgdMsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxBdSGjoaHwRgvB1iZenptQvLjuttwiqSlVehMQGEwILkGK7OnJGk7kNP5WDc7_6jY3fbCX40Rw1_j10HGvenxvMo_eZvw4R8faKpq5Q6i8FSpP-kPgLD3uuh8IbWzRRpR9xtJ0KQbF7k/s400/web2py_SQLFORM_022.jpg&quot; height=&quot;200&quot; width=&quot;400&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;


&lt;h5&gt;SQLFORM.grid のカスタマイズ（新規作成・編集・詳細表示画面）&lt;/h5&gt;

&lt;p&gt;
新規作成や編集、詳細表示画面などもカスタマイズ可能だ。このために次のパラメータが用意されている。

&lt;div style=&quot;padding-left:50px&quot;&gt;
&lt;table border=&quot;1&quot; cellspacing=&quot;0&quot; cellpadding=&quot;3&quot; bordercolor=&quot;#B0B0B0&quot;&gt;
&lt;tr bgcolor=&quot;#d0d0d0&quot;&gt;&lt;th&gt;パラメータ&lt;/th&gt;&lt;th&gt;制御する機能&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;formargs&lt;/td&gt;&lt;td&gt;新規作成・編集・詳細表示画面、共通パラメータ&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;createargs&lt;/td&gt;&lt;td&gt;新規作成画面のみ&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;editargs&lt;/td&gt;&lt;td&gt;編集画面のみ&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;viewargs&lt;/td&gt;&lt;td&gt;詳細表示画面のみ&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;
これらのパラメータには、通常の &lt;strong&gt;SQLFORM&lt;/strong&gt; に指定できるパラメータを辞書値で設定する。サンプルコードを示してみる。

&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@auth.requires_login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;manage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;fields&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image.name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;image.category&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Category&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;links&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;header&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
            &lt;span class=&quot;s&quot;&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                   &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
             &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;download&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                          &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                                 &lt;span class=&quot;n&quot;&gt;_width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}]&lt;/span&gt;

&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;submit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BUTTON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;icon-ok icon-white&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;margin-right: 5px;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;                    &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;OK&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;btn btn-primary&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;cancel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BUTTON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;icon-remove&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;margin-right: 5px;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;                    &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Cancel&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;btn&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;margin-left:10px&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;                    &lt;span class=&quot;n&quot;&gt;_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;reset&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_onclick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;history.back();&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;n&quot;&gt;formargs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;showid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;buttons&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cancel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt;
&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SQLFORM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;download&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;links&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;links&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignore_rw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;hll&quot;&gt;                        &lt;span class=&quot;n&quot;&gt;formargs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;formargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onvalidation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;check_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
サンプルコードでは、id の画面表示を制御する showid の設定を行うと共に、&lt;a href=&#39;http://todayspython.blogspot.com/2012/10/web2py-sqlform-twitter-bootstrap.html&#39;&gt;SQLFORM あれこれ③&lt;/a&gt; で紹介した Twitter Bootstrap を使ったフォームボタンのカスタマイズ（buttons）を行なっている。１５－２０行目でオプションの定義を行い、２６行目で &lt;strong&gt;formargs&lt;/strong&gt; に定義したパラメータを渡している。

&lt;p&gt;
また、１９行目で Cancel ボタンを押した場合、前ページに戻る JavaScript を設定している。これは、一覧ではページネーション（ページ割り）があるためだ。

&lt;p&gt;
&lt;div style=&quot;border: 1px dashed orange;padding:10px&quot;&gt;
&lt;font color=&#39;red&#39;&gt;2012/10/23&lt;/font&gt;&lt;br&gt;
Cancelボタンでは、location.href で page パラメータを指定していました。しかしキチンと動作しなかったため、JavaScript の history.back(); にコードを変更しました。
&lt;/div&gt;

&lt;p&gt;
この他、入力値チェックのために、&lt;strong&gt;onvalidation&lt;/strong&gt; パラメータも指定している。これは &lt;a href=&#39;http://todayspython.blogspot.com/2012/09/web2py-sqlform-sqlform.html&#39;&gt;SQLFORM あれこれ②&lt;/a&gt; で最初に紹介した 次の check_image 関数を指定している。


&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;check_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;file_delete&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;__delete&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;file&amp;#39;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; \
    &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; \
    &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;must enter a url&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;must select a file&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
このコードを実行すると、画面のイメージは次のようになる。

&lt;p&gt;
&lt;table&gt;&lt;tr&gt;&lt;th&gt;新規登録&lt;/th&gt;&lt;th&gt;編集&lt;/th&gt;&lt;th&gt;詳細表示&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;vertical-align:top&quot;&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/Mkv4MJvlP8hj_jD6rjlyfMsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC-bI2mehp1JnZcqaj9jBz-iCayGPyyXho3E2Ft3mKLTyNrY_yvFy791GeOGka_CeeI0H9QsXmgSW7PeWZmSQimQEFJS-r7ms_QJTEpOFT93nC9ec7fYlGP3wlqHtjoro2PAI_xLbD-Kg/s144/web2py_SQLFORM_023.jpg&quot; height=&quot;92&quot; width=&quot;144&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;/td&gt;&lt;td style=&quot;vertical-align:top&quot;&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/WaSPY0L1BwTBIJJh_PGvx8sKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5hmiG61QS4JzRpjuOH0hem0ikJS0PVNMi9PYbgfDKgahLgftZwSuk_CLO_4UmIsoGSs1Vq44l81DA6mciysnGT_6mpSqhKPVPip8OFKeL-Pveoiav4ZnMLA2XYAVBCUxVUZQjyvm9B6w/s144/web2py_SQLFORM_024.jpg&quot; height=&quot;105&quot; width=&quot;144&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;/td&gt;&lt;td style=&quot;vertical-align:top&quot;&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/ABrQYiM3A7rguWjzcmjlmssKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDYS2YKjY8q3aaG1odeq1jxmyG5p1oOkR6pmzqI1JNxn6cMjyI6o-qhxzLlXYPJMU2QN9CDFmgfaD9qHzhtMMfqHqRfsFfpWH1GvS95YT7-DnpAH7P92PiXA91yYA8aTHYMUVOqsEoKK4/s144/web2py_SQLFORM_025.jpg&quot; height=&quot;82&quot; width=&quot;144&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
編集と詳細表示の画面の左上には、&lt;strong&gt;links&lt;/strong&gt; パラメータで設定した画像が表示されている。これは SQLFORM.grid の仕様により、この位置に表示されるようだ。表示・非表示を指定できるパラメータもない。もしこのイメージを非表示にしたい場合は、CSS ファイルに次の記述を追加する（links オプションで、IMGタグの id を image と指定しているため）。

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;nc&quot;&gt;.form_header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;#image&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
このCSSを設定すると、画面表示は次のようになる。


&lt;p&gt;
&lt;table&gt;&lt;tr&gt;&lt;th&gt;編集&lt;/th&gt;&lt;th&gt;詳細表示&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;vertical-align:top&quot;&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/eltMmudu7DHeKl8KH96oJMsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_gtomxO7gGh2VGcNUhfm_bo0ScuxypIUTlLs2Tjzaqy7g0TiSuKh8P0_r1VpBcp6WTV0xYpJkG_MPWH6JbpYFx94cGhz-dl9IlQWPbdKYHUF3iYlO3jU1wHWheHaKVg2WWg5SXap8sa8/s288/web2py_SQLFORM_027.jpg&quot; height=&quot;201&quot; width=&quot;288&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;/td&gt;&lt;td style=&quot;vertical-align:top&quot;&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/BEUi4Xc3juyQiMgJYBVH58sKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg71992gKbZrbPc3QwMNDIQLyhIB5tdnrPS5x_aHk6NkyOaIA2Dks8AmF4aB-0k5eraQaN0_fEGMosuVdcjwU8PCSqZintufk1oo0iB-UoSesTi6tvoscTAGeWsDMz3qVTSe9epee0FaDg/s288/web2py_SQLFORM_026.jpg&quot; height=&quot;169&quot; width=&quot;288&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;br&gt;
以上で、SQLFORM.grid のカスタマイズの説明は終わりです。SQLFORM.grid はとても便利なのですが、カスタマイズには限界があります。例えば、&lt;a href=&#39;http://todayspython.blogspot.com/2012/09/web2py-sqlform-sqlform.html&#39;&gt;SQLFORM あれこれ②&lt;/a&gt; で設定したような、DBテーブルにないフィールドを追加するとか、フィールドの属性追加や設定ができません。また一覧表示でも、編集・削除ボタンの位置変更や、links で設定したフィールドとDBフィールドの位置を入れ替えるなどの設定ができません。

&lt;p&gt;
このため &lt;a href=&#39;http://todayspython.blogspot.com/2012/11/web2py-sqlform-sqltalble.html&#39;&gt;次回&lt;/a&gt; はもう少し柔軟な設定が可能な、&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/others/sqltable.html&#39;&gt;SQLTALBLE&lt;/a&gt; を使ったカスタマイズを紹介したいと思います。

&lt;p&gt;
SQLFORM.grid の他のパラメータについては、web2py Book に説明があります。

&lt;p&gt;
参考： 
&lt;a href=&#39;http://web2py.com/books/default/chapter/33/07#SQLFORM.gridとSQLFORM.smartgrid-(実験的)&#39;&gt;web2py Book - SQLFORM.gridとSQLFORM.smartgrid&lt;/a&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/7188867030168733288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/7188867030168733288'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2012/10/web2py-sqlform-sqlformgrid_18.html' title='web2py SQLFORM あれこれ ⑤　SQLFORM.grid とカスタマイズ２'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvHk_t-VyMpofSkdpmbSq0luqQMu3OrajjKz2Y1Bx1xEZBwUyERm3dS5ic2qf71YG8CM5LzWmW41ZCuhSa1m2rjpJN9cSTDaELpik8HfPjn12aJrlhaBYBx_WQM8SaLL0Bvho28VxjrYk/s72-c/web2py_SQLFORM_014.jpg" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8017294613983746080.post-8321861804006580518</id><published>2012-10-13T09:38:00.001+09:00</published><updated>2023-01-07T00:59:01.632+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web2py"/><title type='text'>web2py SQLFORM あれこれ ④　SQLFORM.grid とカスタマイズ１</title><content type='html'>&lt;p&gt;
&lt;a href=&#39;http://todayspython.blogspot.com/2012/10/web2py-sqlform-twitter-bootstrap.html&#39;&gt;SQLFORM あれこれ ③&lt;/a&gt; の続きです。今回は SQLFORM.grid を使ったカスタマイズを説明します。

&lt;p&gt;
&lt;strong&gt;SQLFORM.grid&lt;/strong&gt; と &lt;strong&gt;SQLFORM.smartgrid&lt;/strong&gt; は、ほぼ同じ機能です。ただ SQLFORM.smartgrid の方が、関連するテーブルの参照やレコードメンテナンスが可能で、少し機能が高度になっています。しかし今回は、SQLFORM.grid を説明します。

&lt;h5&gt;SQLFORM.grid&lt;/h5&gt;

&lt;p&gt;
&lt;a href=&#39;http://todayspython.blogspot.com/2012/09/web2py-sqlform-sqlform.html&#39;&gt;SQLFORM あれこれ ②&lt;/a&gt;　の冒頭で紹介したモデル定義を利用して、試しに次のように SQLFORM.grid を使ったコードを書いてみる。


&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;1
2
3
4&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@auth.requires_login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;manage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SQLFORM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;download&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
少し説明を行うと、&lt;strong&gt;SQLFORM.grid&lt;/strong&gt; は &lt;strong&gt;SQLFORM&lt;/strong&gt; クラスの &lt;strong&gt;スタティックメソッド&lt;/strong&gt; になる。

&lt;p&gt;
第一パラメータとして、&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_query.html#class-query&#39;&gt;Queryオブジェクト&lt;/a&gt; を指定する必要がある。ここでは、&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_dal/class/class_table.html&#39;&gt;Tableオブジェクト&lt;/a&gt; を指定している。これはショートカット機能によって、&lt;code style=&#39;padding:2px 5px; background-color:lavender&#39;&gt;db.image&lt;/code&gt;　は &lt;code style=&#39;padding:2px 5px; background-color:lavender&#39;&gt;db.image.id &gt; 0&lt;/code&gt; に、Tableオブジェクトから Queryオブジェクトに変換される。 

&lt;p&gt;
upload パラメータは、&lt;a href=&#39;http://todayspython.blogspot.com/2012/09/web2py-sqlform.html#uploadfile&#39;&gt;SQLFORM あれこれ ①&lt;/a&gt;　で説明した upload パラメータと同じ機能である。

&lt;p&gt;
このコードを実行してみる。

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/x-6wxnCAD12PX-5kn42e5MsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvHk_t-VyMpofSkdpmbSq0luqQMu3OrajjKz2Y1Bx1xEZBwUyERm3dS5ic2qf71YG8CM5LzWmW41ZCuhSa1m2rjpJN9cSTDaELpik8HfPjn12aJrlhaBYBx_WQM8SaLL0Bvho28VxjrYk/s640/web2py_SQLFORM_014.jpg&quot; height=&quot;348&quot; width=&quot;640&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;p&gt;
画面イメージのように一覧表示になる。SQLFORM.grid では、次の機能を提供する。

&lt;ul&gt;
&lt;li&gt;一覧表示&lt;/li&gt;
&lt;li&gt;検索&lt;/li&gt;
&lt;li&gt;ソート&lt;/li&gt;
&lt;li&gt;ページネーション（ページ割り）&lt;/li&gt;
&lt;li&gt;詳細表示&lt;/li&gt;
&lt;li&gt;編集&lt;/li&gt;
&lt;li&gt;削除&lt;/li&gt;
&lt;li&gt;新規作成&lt;/li&gt;
&lt;li&gt;CSVなどへのエクスポート&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
詳細表示とデータ編集画面イメージは次のようになる。

&lt;table&gt;
&lt;tr&gt;&lt;td&gt;詳細表示画面&lt;/td&gt;&lt;td&gt;変更画面&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/Jkk0XIX-4v4IETttL7pDscsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGBmVdo1XRNfrTQg0slAIkPOvTQJtSIasnR9K9tJug8DZQxdB_V2P6xFA94ITtua3bi2gC-U6He_qzxXJAsAVAbYyIPN2mKI4Rq7PNR7uoBDH6aulz3aeDl-VAHsh_swyeuqdWhkuuzYM/s288/web2py_SQLFORM_015.jpg&quot; height=&quot;175&quot; width=&quot;288&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;/td&gt;&lt;td&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/QUNhAcn42Dz-YFCTEPAnMMsKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVlU4q8a7Qmk591NAfMy09c-c4UjOypi5w72IDaSenQ-Igqdxik-dnFY-vV-14ZsM8dOxC4uXkOmaRzQ31TcFwyTV4b3wqZZayRqzLEmciKc3-0tEh1vcFba4SfiSzhnfwoxdomTzNt6o/s288/web2py_SQLFORM_017.jpg&quot; height=&quot;203&quot; width=&quot;288&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
SQLFORM.grid を利用すれば、それだけでデータ一覧表示やメンテナンス等に活用できる、便利な機能だ。ただ、いろいろ気に入らない部分もあるので、カスタマイズを試してみる。

&lt;h5&gt;SQLFORM.grid のカスタマイズ（アクセス制御）&lt;/h5&gt;

&lt;p&gt;
前のセクションで紹介したコードの一行目で、 &lt;strong&gt;@auth.requires_login()&lt;/strong&gt; と指定している。これはログイン認証を要求するデコレータだが、SQLFORM.grid はログインしていないと編集機能など一部機能を制限するため記述している。この制限は、user_signature パラメータを False で指定すれば解除可能だ。しかしセキュリティ上の問題になるため、通常は解除しない。

&lt;p&gt;
この他、アクセス制御に関しては細かな設定が可能だ。詳細参照・編集・削除・新規作成 の各機能に対して、次のアクセス制御のパラメータが用意されている。

&lt;div style=&quot;padding-left:50px&quot;&gt;
&lt;table border=&quot;1&quot; cellspacing=&quot;0&quot; cellpadding=&quot;3&quot; bordercolor=&quot;#B0B0B0&quot;&gt;
&lt;tr bgcolor=&quot;#d0d0d0&quot;&gt;&lt;th&gt;パラメータ&lt;/th&gt;&lt;th&gt;制御する機能&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;details&lt;/td&gt;&lt;td&gt;詳細参照&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;editable&lt;/td&gt;&lt;td&gt;編集&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;deletable&lt;/td&gt;&lt;td&gt;削除&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;create&lt;/td&gt;&lt;td&gt;新規作成&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;
これらのパラメータに対しては、True/False といったブール値を直接指定しても良いが、特定のグループに属しているか判定するために &lt;a href=&quot;http://docs-hiho.appspot.com/web2py_ac/authorization/implementing_functions.html#tools.Auth.has_membership&quot;&gt;Auth.has_membership&lt;/a&gt; や &lt;a href=&quot;http://docs-hiho.appspot.com/web2py_ac/authorization/implementing_functions.html#tools.Auth.has_permission&quot;&gt;Auth.has_permission&lt;/a&gt; メソッドを指定しても良い。さらに無名関数（lambda）を指定することも可能だ。サンプルを示してみる。

&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@auth.requires_login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;manage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;update&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;delete&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
    &lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SQLFORM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;download&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;details&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;editable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;update&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
                                            &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_membership&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;admin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;deletable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;delete&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
                                            &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_membership&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;admin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;oncreate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;
サンプルコードでは、次のように各パラメータを指定している。

&lt;div style=&quot;padding-left:50px&quot;&gt;
&lt;table border=&quot;1&quot; cellspacing=&quot;0&quot; cellpadding=&quot;3&quot; bordercolor=&quot;#B0B0B0&quot;&gt;
&lt;tr bgcolor=&quot;#d0d0d0&quot;&gt;&lt;th&gt;パラメータ&lt;/th&gt;&lt;th&gt;設定値&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;details&lt;/td&gt;&lt;td&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;editable&lt;/td&gt;&lt;td&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;update&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
             &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_membership&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;admin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;deletable&lt;/td&gt;&lt;td&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;delete&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
             &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_membership&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;admin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;create&lt;/td&gt;&lt;td&gt;

&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;
この設定では、次のように権限を与えている。

&lt;ul&gt;
&lt;li&gt;詳細参照は、ログインユーザなら誰でも可能。&lt;/li&gt;
&lt;li&gt;編集は、対象レコードへの &lt;code style=&#39;padding:2px 5px; background-color:lavender&#39;&gt;update&lt;/code&gt; パーミッションを持っているか、&lt;code style=&#39;padding:2px 5px; background-color:lavender&#39;&gt;admin&lt;/code&gt; グループに属するユーザ。&lt;/li&gt;
&lt;li&gt;削除は、対象レコードへの &lt;code style=&#39;padding:2px 5px; background-color:lavender&#39;&gt;delete&lt;/code&gt; パーミッションを持っているか、&lt;code style=&#39;padding:2px 5px; background-color:lavender&#39;&gt;admin&lt;/code&gt; グループに属するユーザ。&lt;/li&gt;
&lt;li&gt;新規作成は、ログインユーザなら誰でも可能。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
ユーザに対するパーミッションの付与は、１４行目の &lt;strong&gt;onreate&lt;/strong&gt; パラメータに add_permission 関数を割り当てることで実現している。oncreate は指定した関数を、レコード生成時に自動実行する。 

&lt;p&gt;
このコードを実行してみる。

&lt;p&gt;
（&lt;strong&gt;admin グループに属していないユーザ&lt;/strong&gt; で、アクセスした場合）&lt;br&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/V00Bz_HNxMcIoPaoIMSARssKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-aDryGOyECmSvgji7fc_4QLAWwhIFZ_p-u3h2JPaASLYivdwaSNy5C2_o44ZDE5bhbtd_Y2nOEagRKNacKv-5uFHrH1NCSmziTVcxey9QVLz7CUU6f2s3yCGhwGVk9FxDCZIpsmjzZsI/s640/web2py_SQLFORM_018.jpg&quot; height=&quot;299&quot; width=&quot;640&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;p&gt;
（&lt;strong&gt;admin グループに属しているユーザ&lt;/strong&gt; で、アクセスした場合）&lt;br&gt;

&lt;a href=&quot;https://picasaweb.google.com/lh/photo/RtMtdDMi6qPYtl25NGOib8sKua9avpxkz29wiKETsMI?feat=embedwebsite&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFBLaRHf1Ce1fLIjPwuPlKO57UO0H24vafs8aNsTyD61YdqwoLL3GAxAVJlcihSjZqplZqAcKhbAJWGhlgegVs8gLjAX2gZn3abOKczGVxYhUufpAYOaJ1n2QugSWD4eRCRGterms9T14/s640/web2py_SQLFORM_019.jpg&quot; height=&quot;307&quot; width=&quot;640&quot; style=&quot;border: 1px solid #e2e2e2;&quot;/&gt;&lt;/a&gt;

&lt;p&gt;
admin グループに属しているユーザは、全てのレコードの編集・削除が可能だ。admin グループの属していないユーザは、ユーザが作成したレコードしか編集・削除できないのがわかる。

&lt;p&gt;
このコードのままでも問題なく動作するのだが、レコード削除時に削除したレコードのパーミッションのデータが残ってしまうという問題がある。このため、次のようにコードを変更する。


&lt;table class=&quot;highlightable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highligh&quot; style=&quot;overflow:auto;word-wrap:normal&quot;&gt;&lt;pre style=&quot;padding:.5em&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@auth.requires_login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;manage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;update&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;delete&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;del_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;del_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;update&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;del_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;delete&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
&lt;span class=&quot;hll&quot;&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;upd_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FIELDNAME_REQUEST_DELETE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;del_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SQLFORM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;download&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;details&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;editable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;update&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
                                            &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_membership&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;admin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;deletable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;delete&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;\
                                            &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_membership&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;admin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;oncreate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
&lt;span class=&quot;hll&quot;&gt;                &lt;span class=&quot;n&quot;&gt;ondelete&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;del_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onupdate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upd_permission&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
コードを解説すると、del_permission（７行目）と upd_permission（１１行目） という２つの関数を追加している。これを、&lt;strong&gt;ondelete&lt;/strong&gt; 及び &lt;strong&gt;onupdate&lt;/strong&gt; パラメータに割り当てている（２３行目）。ondelete はレコード削除時に実行する関数を、onupdate はレコード更新時に実行する関数を指定する。レコード編集画面で削除を許可している場合、ondelete ではなく onupdate で指定した関数が自動実行されるため、両方指定することが必要だ。

&lt;p&gt;
これによって削除レコードのパーミッションデータを削除することができる。

&lt;p&gt;&lt;br&gt;
記事が長くなったので、&lt;a href=&#39;http://todayspython.blogspot.com/2012/10/web2py-sqlform-sqlformgrid_18.html&#39;&gt;次回&lt;/a&gt; に続きます。次回も、SQLFOM.grid カスタマイズを更に説明します。なお次のサイトも参考にしてください。

&lt;p&gt;
参考&lt;br&gt;
&lt;a href=&#39;http://web2py.com/books/default/chapter/33/07#SQLFORM.gridとSQLFORM.smartgrid-(実験的)&#39;&gt;web2py Book - SQLFORM.gridとSQLFORM.smartgrid&lt;/a&gt;&lt;br&gt;
&lt;a href=&#39;http://docs-hiho.appspot.com/web2py_ac/access_control.html&#39;&gt;web2py 補足ドキュメント - アクセス制御 - Access control&lt;/a&gt;

 &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div style=&quot;width:300px;&quot;&gt;

&lt;a href=&quot;http://blog.with2.net/link.php?1184731&quot;&gt;&lt;img src=&quot;http://image.with2.net/img/banner/banner_21.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;人気ブログランキングへ&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.blogmura.com/&quot;&gt;&lt;img src=&quot;http://www.blogmura.com/img/www88_31_1.gif&quot; width=&quot;88&quot; height=&quot;31&quot; border=&quot;0&quot; alt=&quot;ブログランキング・にほんブログ村へ&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8321861804006580518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8017294613983746080/posts/default/8321861804006580518'/><link rel='alternate' type='text/html' href='http://todayspython.blogspot.com/2012/10/web2py-sqlform-sqlformgrid.html' title='web2py SQLFORM あれこれ ④　SQLFORM.grid とカスタマイズ１'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvHk_t-VyMpofSkdpmbSq0luqQMu3OrajjKz2Y1Bx1xEZBwUyERm3dS5ic2qf71YG8CM5LzWmW41ZCuhSa1m2rjpJN9cSTDaELpik8HfPjn12aJrlhaBYBx_WQM8SaLL0Bvho28VxjrYk/s72-c/web2py_SQLFORM_014.jpg" height="72" width="72"/></entry></feed>