暗号通貨.py

ビットコインやブロックチェーンの技術に衝撃を受け、プログラミングの勉強を開始。現在はPythonを勉強中。

Python

Pyramidチュートリアルを辿る⑥Viewsの定義とルーティングの追加

前回の続きです。

前回はmodelの編集を行いました。

今回は実際にwikiアプリケーションを作成するための作業をします。

チュートリアルはこのページからです。

http://docs.pylonsproject.org/projects/pyramid/en/latest/tutorials/wiki2/definingviews.html

docutilsライブラリの追加

DocutilsとはreStructuredTextという構文で構造化されたテキストファイルを, HTML,XMLなどのフォーマットに変換することができるpythonライブラリのようです。

bcryptをインストールしたときのように、myproject/setup.pyのrequiresに'docutils'を追加し、インストールを再度実行します。

$ pip install -e .

Successfully installed docutils-0.13.1 myproject

これでdocutilsが使えるようになります。

ルーティングの追加

以前の記事でルーティングについて学び簡単にまとめたことを思い出します。

  1. __init__.pyでルートのincludeとscan
  2. routes.pyでadd_routeでroute名の登録
  3. views内のファイルでデコレータを使ってレンダリング処理、指定したページを表示

1のinit.pyの編集は終わっているので、ルーティングを追加する場合は2からになりますね。

routes.pyを編集します。

スポンサーリンク

adsense

スポンサーリンク

myproject/routes.py

def includeme(config):
    config.add_static_view('static', 'static', cache_max_age=3600)
    # config.add_route('home', '/') 削除
    config.add_route('view_wiki', '/')
    config.add_route('view_page', '/{pagename}')
    config.add_route('add_page', '/add_page/{pagename}')
    config.add_route('edit_page', '/{pagename}/edit_page')

下4行が追加部分です。

'view_wiki'、'view_page'、'add_page'、'edit_page'という4つのルート名を登録しました。

このルートをviewsで定義します。

views/default.py

import cgi
import re
from docutils.core import publish_parts

from pyramid.httpexceptions import (
    HTTPFound,
    HTTPNotFound,
    )

from pyramid.view import view_config

from ..models import Page, User

# regular expression used to find WikiWords
wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)")

@view_config(route_name='view_wiki')
def view_wiki(request):
    next_url = request.route_url('view_page', pagename='FrontPage')
    return HTTPFound(location=next_url)

@view_config(route_name='view_page', renderer='../templates/view.jinja2')
def view_page(request):
    pagename = request.matchdict['pagename']
    page = request.dbsession.query(Page).filter_by(name=pagename).first()
    if page is None:
        raise HTTPNotFound('No such page')

    def add_link(match):
        word = match.group(1)
        exists = request.dbsession.query(Page).filter_by(name=word).all()
        if exists:
            view_url = request.route_url('view_page', pagename=word)
            return '<a href="%s">%s</a>' % (view_url, cgi.escape(word))
        else:
            add_url = request.route_url('add_page', pagename=word)
            return '<a href="%s">%s</a>' % (add_url, cgi.escape(word))

    content = publish_parts(page.data, writer_name='html')['html_body']
    content = wikiwords.sub(add_link, content)
    edit_url = request.route_url('edit_page', pagename=page.name)
    return dict(page=page, content=content, edit_url=edit_url)

@view_config(route_name='edit_page', renderer='../templates/edit.jinja2')
def edit_page(request):
    pagename = request.matchdict['pagename']
    page = request.dbsession.query(Page).filter_by(name=pagename).one()
    if 'form.submitted' in request.params:
        page.data = request.params['body']
        next_url = request.route_url('view_page', pagename=page.name)
        return HTTPFound(location=next_url)
    return dict(
        pagename=page.name,
        pagedata=page.data,
        save_url=request.route_url('edit_page', pagename=page.name),
        )

@view_config(route_name='add_page', renderer='../templates/edit.jinja2')
def add_page(request):
    pagename = request.matchdict['pagename']
    if request.dbsession.query(Page).filter_by(name=pagename).count() > 0:
        next_url = request.route_url('edit_page', pagename=pagename)
        return HTTPFound(location=next_url)
    if 'form.submitted' in request.params:
        body = request.params['body']
        page = Page(name=pagename, data=body)
        page.creator = (
            request.dbsession.query(User).filter_by(name='editor').one())
        request.dbsession.add(page)
        next_url = request.route_url('view_page', pagename=pagename)
        return HTTPFound(location=next_url)
    save_url = request.route_url('add_page', pagename=pagename)
    return dict(pagename=pagename, pagedata='', save_url=save_url)

それぞれに関数が追加されました。細かい機能は後回しにします。

viewでルーティングを定義し、表示したいページを指定しました。

そのページ、つまりtemplatesの編集に取り掛かります。

templates/layout.jinja2

<!DOCTYPE html>
<html lang="{{request.locale_name}}">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="pyramid web application">
    <meta name="author" content="Pylons Project">
    <link rel="shortcut icon" href="{{request.static_url('tutorial:static/pyramid-16x16.png')}}">

    <title>{% block subtitle %}{% endblock %}Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title>

    <!-- Bootstrap core CSS -->
    <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom styles for this scaffold -->
    <link href="{{request.static_url('tutorial:static/theme.css')}}" rel="stylesheet">

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%2F%2Foss.maxcdn.com%2Flibs%2Fhtml5shiv%2F3.7.0%2Fhtml5shiv.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
      <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%2F%2Foss.maxcdn.com%2Flibs%2Frespond.js%2F1.3.0%2Frespond.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
    <![endif]-->
  </head>

  <body>

    




<div class="starter-template">

<div class="container">

<div class="row">

<div class="col-md-2">
            <img class="logo img-responsive" src="{{request.static_url('tutorial:static/pyramid.png') }}" alt="pyramid web framework">
          </div>


<div class="col-md-10">

<div class="content">
            {% block content %}{% endblock %}
            </div>





          </div>





        </div>


<div class="row">

<div class="copyright">
            Copyright &copy; Pylons Project
          </div>





        </div>





      </div>





    </div>







    <!-- Bootstrap core JavaScript ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%2F%2Foss.maxcdn.com%2Flibs%2Fjquery%2F1.10.2%2Fjquery.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%2F%2Foss.maxcdn.com%2Flibs%2Ftwitter-bootstrap%2F3.0.3%2Fjs%2Fbootstrap.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
  </body>
</html>

チュートリアルのページでは変更点だけハイライトされているのでわかりやすいです。

次にview.jinja2とedit.jinja2というファイルを新しく作成します。

templates/view.jinja2

{% extends 'layout.jinja2' %}

{% block subtitle %}{{page.name}} - {% endblock subtitle %}

{% block content %}


{{ content|safe }}



<a href="{{ edit_url }}">
    Edit this page
</a>




    Viewing <strong>{{page.name}}</strong>, created by <strong>{{page.creator.name}}</strong>.




You can return to the
<a href="{{request.route_url('view_page', pagename='FrontPage')}}">FrontPage</a>.


{% endblock content %}

jinja2という拡張子になにか違和感がありますが気にせずいきましょう。笑

templates/edit.jinja2

{% extends 'layout.jinja2' %}

{% block subtitle %}Edit {{pagename}} - {% endblock subtitle %}

{% block content %}


Editing <strong>{{pagename}}</strong>




You can return to the
<a href="{{request.route_url('view_page', pagename='FrontPage')}}">FrontPage</a>.





<form action="{{ save_url }}" method="post">

<div class="form-group">
    <textarea class="form-control" name="body" rows="10" cols="60">{{ pagedata }}</textarea>
</div>


<div class="form-group">
    <button type="submit" name="form.submitted" value="Save" class="btn btn-default">Save</button>
</div>



</form>



{% endblock content %}

リクエストが404 not foundだったときのレスポンスを変更します。

templates/404.jinja2

{% extends "layout.jinja2" %}

{% block content %}


<div class="content">

<h1><span class="font-semi-bold">Pyramid tutorial wiki</span> <span class="smaller">(based on TurboGears 20-Minute Wiki)</span></h1>




<span class="font-semi-bold">404</span> Page Not Found

</div>


{% endblock content %}

このルーティングはviews内のnotfound.pyでされています。

ここまでできればサーバーを起動し、アプリケーションがちゃんとできているか確認しましょう。

$ pserve development.ini --reload

http://localhost:6543/に飛びます。

http://localhost:6543/FrontPageに飛んでいるはずです。

なぜか画像がうまく表示されていませんね。

ページを編集してみます。「Edit this page」へ。

「はじめてのPyramid」と追記して「save」します。

再びFrontPageにいくと「はじめてのPyramid」が保存されているはずです。

されていますね!

一応基本的なことはここまでで終わりなのかと思います。

あとは認証や権限機能の追加、テストの実行をチュートリアルでやっていますが、コピペばかりになってしまって記事にしてもあまり意味がなさそうなので、Pyramidのチュートリアルを辿るのは本記事で終わりとします。

オリジナルのアプリケーションなんかも作っていきたいのですが、慣れるまで大変そうなので時間を見ながらやっていきます。

がんばっていきまっしょい。

日本で一番簡単にビットコインが買える取引所 coincheck bitcoin

-Python