Google App Engine 上で webapp ばかり触ってたけど、Python なら Django だろう!ということでまずは tutorial をやってみた。
django のバージョンは1.1にした。なんでかというと GAE で動かす事が前提だから。今のところサポートされているのが1.1まで、だったきがする。
インストール
Django公式サイトからダウンロードしてきたtarボールを解凍して
$ python setup.py install
とする。俺みたいに Python を複数バージョン入れている場合は、実行する Python のバージョンに注意。
windows の場合は
c:\\Python26\
と
c:\\Python26\Lib\site-packages\django\bin\
を PATH に入れておくと後で便利。というかやらんと不便すぎて死ぬ。
Linux と Mac は知らない。
後は使ったコマンドと最終結果だけ。
詳しくは tutorial を参考にしていただければ。
Django | Writing your first Django app, part 1 | Django documentation
$ python django-admin.py startproject mysite
$ ls
mysite
$ cd mysite/
mysite$ ls
__init__.py manage.py settings.py urls.py
mysite$ python manage.py runserver
Validating models...
0 errors found
Django version 1.1.2, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
mysite$ python manage.py syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username: ryomatsu
E-mail address: hoge@example.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
mysite$ python manage.py startapp polls
mysite$ ls polls
__init__.py models.py tests.py views.py
mysite$ gvim polls/models.py
mysite$ python manage.py sql polls
BEGIN;
CREATE TABLE "polls_poll" (
"id" integer NOT NULL PRIMARY KEY,
"question" varchar(200) NOT NULL,
"pub_date" datetime NOT NULL
)
;
CREATE TABLE "polls_choice" (
"id" integer NOT NULL PRIMARY KEY,
"poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
"choice" varchar(200) NOT NULL,
"votes" integer NOT NULL
)
;
COMMIT;
mysite$ python manage.py syncdb
Creating table polls_poll
Creating table polls_choice
Installing index for polls.Choice model
最終的なソースコードとディレクトリ構成
ソースコードはチュートリアル最後にあるgenericなコードになっている。
mysite$ ls -R
.:
__init__.py manage.py settings.py sqlite3.db urls.py
__init__.pyc polls settings.pyc templates urls.pyc
./polls:
__init__.py admin.py models.py tests.py urls.pyc views.pyc
__init__.pyc admin.pyc models.pyc urls.py views.py
./templates:
admin polls
./templates/admin:
base_site.html
./templates/polls:
poll_detail.html poll_list.html results.html
mysite/manage.py
# 初期値
mysite/settings.py
# 変更点のみ記載
...
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'C:/data/project/django/mysite/sqlite3.db'
...
TEMPLATE_DIRS = (
"C:/data/project/django/mysite/templates",
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'mysite.polls',
'django.contrib.admin',
)
mysite/urls.py
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^polls/', include('mysite.polls.urls')),
(r'^admin/', include(admin.site.urls)),
)
mysite/polls/urls.py
from django.conf.urls.defaults import *
from mysite.polls.models import Poll
info_dict = {
'queryset': Poll.objects.all(),
}
urlpatterns = patterns('',
(r'^$', 'django.views.generic.list_detail.object_list',info_dict),
(r'^(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict),
url(r'^(?P<object_id>\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results.html'), 'poll_results'),
(r'^(?P<poll_id>\d+)/vote/$', 'mysite.polls.views.vote'),
)
# not generic code
#urlpatterns = patterns('mysite.polls.views',
# (r'^$', 'index'),
# (r'^(?P<poll_id>\d+)/$', 'detail'),
# (r'^(?P<poll_id>\d+)/results/$', 'results'),
# (r'^(?P<poll_id>\d+)/vote/$', 'vote'),
#)
mysite/polls/admin.py
from mysite.polls.models import Poll
from mysite.polls.models import Choice
from django.contrib import admin
#class ChoiceInline(admin.StackedInline):
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 3
class PollAdmin(admin.ModelAdmin):
#fields = ['pub_date', 'question']
fieldsets = [
(None, {'fields': ['question']}),
#('Date informatin', {'fields': ['pub_date']}),
('Date informatin', {'fields': ['pub_date'], 'classes':['collapse']}),
]
inlines = [ChoiceInline]
list_display = ('question', 'pub_date', 'was_published_today')
list_filter = ['pub_date']
search_fields = ['question']
date_hierarchy = 'pub_date'
admin.site.register(Poll, PollAdmin)
admin.site.register(Choice)
mysite/polls/models.py
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 Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
def __unicode__(self):
return self.choice
mysite/polls/views.py
from mysite.polls.models import Poll, Choice
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.template import Context, loader
from django.shortcuts import render_to_response, get_object_or_404
from django.core.urlresolvers import reverse
# no generic code
#def index(request):
# latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
# return render_to_response('polls/poll_list.html', {'latest_poll_list': latest_poll_list})
# #t = loader.get_template('polls/index.html')
# #c = Context({
# # 'latest_poll_list': latest_poll_list,
# #})
# #return HttpResponse(t.render(c))
#def detail(request, poll_id):
# p = get_object_or_404(Poll, pk=poll_id)
# #try:
# # p=Poll.objects.get(pk=poll_id)
# #except Poll.DoesNotExist:
# # raise Http404
# return render_to_response('polls/poll_detail.html', {'poll':p})
#def results(request, poll_id):
# p = get_object_or_404(Poll, pk=poll_id)
# return render_to_response('polls/results.html', {'poll':p})
def vote(request, poll_id):
p = get_object_or_404(Poll, pk=poll_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': "You didn't select a choice",
})
else:
selected_choice.votes += 1
selected_choice.save()
return HttpResponseRedirect(reverse('poll_results', args=(p.id,)))
mysite/templates/admin/base_site.html
{% extends "admin/base.html" %}
{% load i18n %}
{% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %}
{% block branding %}
<h1 id="site-name">{% trans 'mysite' %}</h1>
{% endblock %}
{% block nav-global %}{% endblock %}
mysite/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="Vote" />
</form>
mysite/templates/polls/poll_list.html
{% if object_list %}
<ul>
{% for poll in object_list %}
<li>{{ poll.question }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
mysite/templates/polls/results.html
<h1>{{ object.question }}</h1>
<ul>
{% for choice in object.choice_set.all %}
<li>{{ choice.choice }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>