牌語備忘録 -pygo

あくまでもメモです。なるべくオフィシャルの情報を参照してください。

牌語備忘録 -pygo

速攻でDjango0.97のチュートリアルをやってみた

速攻でhttp://michilu.com/django/doc-ja/index/(0.97pre SVN)のチュートリアルをやってみた。


プロジェクトの作成

例ホームにプロジェクトを作る。
コマンドラインから

cd
django-admin.py startproject mysite

mysite ディレクトリが作成され、中に必要なファイルが入ってる。

  • mysite/
    • __init__.py
    • manage.py
    • settings.py
    • urls.py

settings.py で設定

mysite/settings.py を編集する。

ファイル先頭に以下いれる。

# *-# -*- coding: utf-8 -*-
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

その他も書き換え

DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = os.path.join(BASE_DIR, 'database.db')

#...

TIME_ZONE = 'Asia/Tokyo'
LANGUAGE_CODE = 'ja'

#...

TEMPLATE_DIRS = (
    os.path.join(BASE_DIR, 'templates'),
    )

#...

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin', #admin サイトの有効化(後述)
    'mysite.polls' #モデルも追加(後述)
)

モデルの作成

コマンドラインから

cd ~/mysite/
python manage.py startapp polls

でmysiteにpollsディレクトリ以下が作成される。

  • polls/
    • __init__.py
    • models.py
    • views.p


polls/models.pyを編集

# *-# -*- coding: utf-8 -*-
from django.db import models
import datetime

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    def __unicode__(self):
        return self.question
    def was_published_today(self):
        return self.pub_date.date() == datetime.date.today()
    was_published_today.short_description = 'Published today?'

    class Admin:    #Poll モデルを admin で編集できるようにする
        fields = (
            (None, {'fields': ('question',)}),
            ('Date information', {'fields': ('pub_date',)}),
            )
        list_display = ('question', 'pub_date', 'was_published_today')
        list_filter = ['pub_date']
        search_fields = ['question']
        date_hierarchy = 'pub_date'


class Choice(models.Model):
    #models.ForeignKeyでリレーションを張ったオブジェクトの追加
    poll = models.ForeignKey(Poll, edit_inline=models.TABULAR,
                         num_in_admin=3) 
    choice = models.CharField(max_length=200, core=True)
    votes = models.IntegerField(core=True)
    def __unicode__(self):
        return self.choice

    class Admin:    #Choiceモデルもadminで編集できるようにする
        pass

urls.py ファイルを編集

mysite/urls.pyを編集

# *-# -*- coding: utf-8 -*-
from django.conf.urls.defaults import *

urlpatterns = patterns('',
                       #admin サイトの有効化
                       (r'^admin/', include('django.contrib.admin.urls')),
                       #URLconf の脱カップリング
                       (r'^polls/', include('mysite.polls.urls')),
                       )

汎用ビューを使う

mysite/urls.py ファイルを mysite/polls/urls.pyにコピーしてpolls/urls.pyを編集。

# *-# -*- coding: utf-8 -*-
from django.conf.urls.defaults import *
from mysite.polls.models import Poll

info_dict = {
    'queryset': Poll.objects.all()
    }

urlpatterns = patterns('',
                        (r'^(?P<object_id>\d+)/vote/$',
                         'mysite.polls.views.vote'),
                        )
#汎用ビュー使用
urlpatterns += patterns('django.views.generic',
                       (r'^$', 'list_detail.object_list', info_dict),
                       (r'^(?P<object_id>\d+)/$',
                        'list_detail.object_detail', info_dict),
                       url(r'^(?P<object_id>\d+)/results/$',
                           'list_detail.object_detail',
                           dict(info_dict, template_name='polls/results.html'),
                           'poll_results'),
                       )

テンプレート作成

mysiteにtemplatesディレクトリを作り、その中にまたpollsディレクトリを作って以下ファイルを作成。

templates/polls/poll_list.html

{% if object_list %}
<ul>
  {% for object in object_list %}
  <li>{{ object.question }}</li>
  {% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}


templates/polls/poll_detail.html

<h1>{{ object.question }}</h1>

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="/polls/{{ object.id }}/vote/" method="post">
{% for choice in object.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}"
       value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br />
{% endfor %}
<input type="submit" value="投票する" />
</form>


templates/polls/results.html

<h1>{{ object.question }}</h1>

<ul>
{% for choice in object.choice_set.all %}
    <li>{{ choice.choice }} -- {{ choice.votes }} 票</li>
{% endfor %}
</ul>

views.py に vote() 関数を作る

polls/view.pyを編集

# *-# -*- coding: utf-8 -*-
from django.shortcuts import get_object_or_404, render_to_response
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from mysite.polls.models import Choice, Poll

def vote(request, object_id):
    p = get_object_or_404(Poll, pk=object_id)
    try:
        selected_choice = p.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        return render_to_response('polls/poll_detail.html', {
            'object': p,
            'error_message': "選択肢を選んでいません。",
            })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # ユーザが Back ボタンを押して同じフォームを提出するのを防ぐ
        # ため、POST データを処理できた場合には、必ず
        # HttpResponseRedirect を返すようにします。
        return HttpResponseRedirect(reverse('poll_results', args=(p.id,)))

syncdbする

コマンドラインから

cd ~/mysite/
python manage.py syncdb

ここでスーパユーザのアカウントを作成を尋ねるプロンプトがでるので入力する(ユーザネーム、メアドはとりあえず適当に)

  • Would you like to create one now? (yes/no): yes
  • Username : username
  • E-mail address: username@u.com
  • Password: ****
  • Password (again): ****

admin サイト(管理画面)に入る

コマンドラインから

cd ~/mysite/
python manage.py runserver

で開発用サーバをたちあげhttp://127.0.0.1:8000/admin/ にアクセスして管理画面へ。

adminサイトでテストデータ追加

Pollsの追加をクリックして、Question:に「What's up」とか入力。
日付、時刻も適当に入力して保存。

同様にChoiceも追加。
とりあえずPoll:の「What's up」を選んで、Choice:に「The sky」、Votes:は「0」とかいれとく。
同じようにChoice:「Just hacking again」もとりあえず追加しとく。

確認

http://127.0.0.1:8000/pollsで表示できてるか確認。
http://127.0.0.1:8000/polls/1/で投票とかしてみる。(ラジオボタンをチェックしないで投票するとかも)


おしまい。