django思い出しメモ

Django

環境立ち上げ

python3 -m venv env
source env/bin/activate

プロジェクト作成

django-admin startproject プロジェクト名

アプリ作成

python manage.py startapp アプリ名

サーバの起動

python manage.py runserver

リクエストハンドラーの作成

from django import HttpResponse

def index(request):
    return HttpResponse("Hello")
  • ビューをurlと紐付ける

1. app/urls.pyを作成する
2.app/urls.pyに追加する

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]

3.project/urls.pyに追加する

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('polls/', include('polls.urls')),
    path('admin/', admin.site.urls),
]

path関数の説明

1.path() 引数: route----------------------------------------------------

route は URL パターンを含む文字列です。リクエストを処理するとき、Django は urlpatterns のはじめのパターンから開始し、リストを順に下に見ていきます。要求された URL を一致するものを見つけるまで各パターンと比較します。

パターンはGETやPOSTのパラメーター、そしてドメイン名を検索しません。例えば、 https://www.example.com/myapp/ へのリクエストにおいては、URLconfは myapp/ を見ます。 https://www.example.com/myapp/?page=3 へのリクエストにおいても、URLconfは myapp/ を見ます。


2.path() 引数: view----------------------------------------------------

Django がマッチする正規表現を見つけると、 Django は指定されたビュー関数を呼び出します。その際は HttpRequest オブジェクトを第一引数に、そしてキーワード引数としてrouteから「キャプチャされた」値を呼び出します。この例はこの後すぐ出てきます。


3.path() 引数: kwargs----------------------------------------------------

任意のキーワード引数を辞書として対象のビューに渡せます。この機能はチュートリアルでは使いません。


4path() 引数: name----------------------------------------------------

URL に名前付けをしておけば Django のどこからでも明確に参照でき、とくにテンプレートの中で有効です。この便利な機能のおかげで、プロジェクトのURLにグローバルな変更を加える場合にも1つのファイルを変更するだけで済むようになります。

データベースバインディング·コンフィグレーション

1. 関連リンクDjango のインストール方法 | Django ドキュメント | Django
2. DATABASES の 'default' 項目内の以下のキーをデータベースの接続設定に合うように変更してください。

ENGINE -- 'django.db.backends.sqlite3'、 'django.db.backends.postgresql'、 'django.db.backends.mysql' または 'django.db.backends.oracle' のいずれかにします。その他のバックエンド も利用可能です。
NAME -- データベースの:setting:NAME です。SQLiteを使用している場合、データベースはコンピュータ上のファイルになります。デフォルト値の BASE_DIR / 'db.sqlite3' は、プロジェクトディレクトリにファイルを保存します。

USER や PASSWORD そして HOST などの追加設定を加える必要があります

3.sqlite以外の場合
もし SQLite 以外を使っている場合、 database を今のうちに作っておいてください。 "CREATE DATABASE database_name;" とデータベースのインタラクティブプロンプトで実行してください。

mysite/settings.py のデータベースユーザに 「データベース作成」の権限があるならばDB を自動作成することができます。

詳細リンク設定 | Django ドキュメント | Django

4.project/settings.py を編集する際、 TIME_ZONE に自分のタイムゾーンも設定します。

基本DBの作成

djangoインスタンスを起動するには最低1つのDBを取り扱うのでその準備をしなければなりません。

python manage.py migrate

これで準備完了です。

モデルの作成

from django.db import models

class MyModel(models.Model):
     data1 = models.CharField(max_length=100)

アプリ用DBの作成

1.Djangoインスタンス(project/settings.py)にアプリを登録する

INSTALLED_APPS = [
    ~~~~
    'polls.apps.PollsConfig',
]

2. マイグレーションの作成
python manage.py makemigrations アプリ名
3.マイグレイトの実行
python manage.py migrate

可読性をあげる1(strを使えるようにする)

モデルに__str__メソッドを追加する。

def __str__(self):
        return self.member

urlパターン マッチングをする

path('<int:some_integer>/detail/', views.my_view, "description")

templateの使用

1.app/templates/app/を作成
2.上記ディレクトリ にhtmlファイルを作成
3.viewで使用する
loaderを使用する場合

from django.http import HttpResponse
from django.template import loader

from .models import Question


def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    template = loader.get_template('polls/index.html')
    context = {
        'latest_question_list': latest_question_list,
    }
    return HttpResponse(template.render(context, request))

renderを使用する場合

from django.shortcuts import render

from .models import Question


def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)

404エラーハンドリング

ショートカットなし

from django.http import Http404
from django.shortcuts import render

from .models import Question
# ...
def detail(request, question_id):
    try:
        question = Question.objects.get(pk=question_id)
    except Question.DoesNotExist:
        raise Http404("Question does not exist")
    return render(request, 'polls/detail.html', {'question': question})

ショートカット有り

from django.shortcuts import get_object_or_404, render

from .models import Question
# ...
def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})

テンプレートシステムの基本

1.for文

{% for a in b %}
~~~
{% endfor %}

2.if文

{%  if contidtion %}
~~~
{% else %}
~~~
{% endif %}

3.式

{{ a.attribute }}

urlのハードコーディングを避ける。

基本イディオム

{% url 'urls.pyのnameに対応する文字列' %}

もし他のアプリケーションでも同じnameのビューがあった場合の対処法
app/urls.pyでapp_nameの定義をし、url関数の引数を変更する。

app_name = 'myapp'
{% url 'myapp:detail' %}

csrf_tokenの使用

<form action="~~~" method="post">
{% csrf_token %}
<input ~~~>
<input type="submit" >
</form>

POSTデータの取り出し

request.POST['key']

リダイレクト

HttpResponseRedirectを使用する引数にはurlを渡す。

urlの作成

reverse関数を使用する

reverse('app:name', args=(パラメータ))

汎用ビュー(リストビュー)の使用

class ItemsView(generic.ListView):
    template_name = 'app/items.html'
    context_object_name = 'latest_item_list'

    def get_queryset(self):
        return MyModel.objects.order_by('-pub_date')[:5]

get_querysetをオーバーライドすることでビューに渡すデータを変更できる
template_nameで使うテンプレートを指定できる

汎用ビュー(デテールビュー)の使用

詳細ページを作成するときに使う

class ItemView(generic.DetailView):
    model = MyModel
    template_name = "app/item.html"

決まり
templateではmodel名を小文字にした物が変数として使われる。
詳細ビューのデータ取得にはurlのpkを使っているので
urls.pyの文字列で/itemのようにしないといけない
template_nameで使うテンプレートを指定できる

testを書く

書く場所はapp/tests.py

#基本形
import datetime

from django.test import TestCase
from django.utils import timezone

from .models import Question


class QuestionModelTests(TestCase):

    def test_was_published_recently_with_future_question(self):
        """
        was_published_recently() returns False for questions whose pub_date
        is in the future.
        """
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(pub_date=time)
        self.assertIs(future_question.was_published_recently(), False)

1.TestCaseを継承したクラスを作成する。
2.

python manage.py test app

を実行することでtest_で始まるメソッドが端から実行される

ビューのテストを書く

# 基本形
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'], [])

静的要素の使用

1.app/static/app/を作成
2.上記ディレクトリ ないに静的ファイルを設置
3.テンプレートで読みこむ

{% load static %}

<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}">

Django Adminの使用

管理ユーザの作成

python manage.py createsuperuser

admin機能の使用

1./admin/にアクセスします
2.ログインします

アプリをadminに登録する。

app/admin.pyに下記のコードを追加する

from .models import Question

admin.site.register(Question)

フォームの変更

モデルの admin のオプションを変更したいときには、モデルごとに admin クラスを作成して、 admin.site.register() の 2 番目の引数に渡すと いうパターンに従ってください。
ex. app/admin.py

from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question_text']

admin.site.register(Question, QuestionAdmin)

この例ではフォームの並び順を変更しています。

リレーションオブジェクトの追加

class ChoiceInline(admin.StackedInline):
    model = Choice
    extra = 3

class QuestionAdmin(admin.ModelAdmin):
   ~~~
    inlines = [ChoiceInline]

オブジェクト一覧ページの変更

class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date', 'was_published_recently')

フィルタリング 検索

class Question(models.Model):
    # ...
    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'
list_filter = ['pub_date']
search_fields = ['question_text']

adminテンプレートのカスタム

1.設定ファイル (mysite/settings.py) を開いて、TEMPLATES 設定オプションの中に、次のように DIRS オプションを追加します。

    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'], # ここ
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

2.manage.pyと同じ階層にtemplates/admin/を作成しましょう
3.django/contrib/admin/templates/admin/base_site.htmlを2のディレクトリ にコピーします。
4.お好きなように編集してください。

django.contrib.admin.AdminSiteを変更すれば一部の値は簡単に変更できる。