#Djangoのチュートリアル終了
一応基本的なところまでは終了した、と思う。
で、やっぱりこのチュートリアルで一番気になるのは「いやいや、viewもmodelもファイルが一枚岩じゃん、これじゃ分散開発に向いてなくね?」というところ。
さすがにviewとmodelとtestくらいは分割するべきじゃないの?ということで分割してみた。
なお、基本的な情報はここを参照しました。感謝。
たとえばtestsの分割後の状態はこんな感じ。
testsの下にサブディレクトリとしてmodelとviewが切ってあってそこを参照するための__init__.py
の中身がこんな感じになっている。
from polls.tests.model import *
from polls.tests.view import *
それぞれのディレクトリの__init__.py
で各テストクラスを記述したファイルの参照を記述する。
from polls.tests.model.questionTest import *
from polls.tests.view.indexTest import *
from polls.tests.view.detailTest import *
from polls.tests.view.createModels import *
モジュール名とクラス名はわざと別にしてあったりする。
from django.test import TestCase
from django.urls import reverse
from polls.models import Question
from .createModels import create_question
class QuestionIndexViewTests(TestCase):
def test_no_questions(self):
"""
If no questions exist, an appropriate message is displayed.
"""
response = self.client.get(reverse('polls:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "No polls are available.")
self.assertQuerysetEqual(response.context['latest_question_list'], [])
def test_past_question(self):
"""
Questions with a pub_date in the past are displayed on the
index page.
"""
create_question(question_text="Past question.", days=-30)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question.>']
)
def test_future_question(self):
"""
Questions with a pub_date in the future aren't displayed on
the index page.
"""
create_question(question_text="Future question.", days=30)
response = self.client.get(reverse('polls:index'))
self.assertContains(response, "No polls are available.")
self.assertQuerysetEqual(response.context['latest_question_list'], [])
def test_future_question_and_past_question(self):
"""
Even if both past and future questions exist, only past questions
are displayed.
"""
create_question(question_text="Past question.", days=-30)
create_question(question_text="Future question.", days=30)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question.>']
)
def test_two_past_questions(self):
"""
The questions index page may display multiple questions.
"""
create_question(question_text="Past question 1.", days=-30)
create_question(question_text="Past question 2.", days=-5)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question 2.>', '<Question: Past question 1.>']
)
共通関数としてテスト用のModelであるQuestionのインスタンスを作るコードを分離して別ファイルへ。
import datetime
from django.utils import timezone
from polls.models import Question
def create_question(question_text, days):
"""
Create a question with the given `question_text` and published the
given number of `days` offset to now (negative for questions published
in the past, positive for questions that have yet to be published).
"""
time = timezone.now() + datetime.timedelta(days=days)
return Question.objects.create(question_text=question_text, pub_date=time)
実際from ... import ...
の書き方に慣れてなくててこずったりしました。
もうだいたいわかった(気がする)けど。
要するにこういうことよね。
from {アプリケーション名|ライブラリ名}.{ディレクトリ名(.サブディレクトリ名)}.{モジュール名(=ファイル名)} import {クラス名|関数名}
あと、import *
の書き方は本当は邪道なんだろうけど、__init__.py
の中でだけは許してほしいところ。ていうか__init__.py
くらい自動生成してほしいんだけどPyCharmだったらできたりすんのかな。
え?自分で書け?w
コードはGitHubに置いてあったりします。あんまり面白みないけどね。
さて、こっからは排他制御とトランザクションの仕組みを見ないとね。
というわけでこの記事はここまで。