Django
django django
Published: 2018-06-28

Djangoの重要コマンド、設計パターンのまとめ。

Django クイックリファレンス

コマンドライン操作

バージョン確認

$ python -m django --version

プロジェクト作成

$ django-admin startproject mysite
$ cd mysite

開発用サーバー起動

$ python manage.py runserver
$ python manage.py runserver 8080  # ポート指定

アプリケーションを作る(Scaffoldのイメージ)

$ python manage.py startapp polls

マイグレーション

マイグレーションを実行する。

$ python manage.py migrate
$ python manage.py migrate --run-syncdb

モデルを有効にする

マイグレーションのSQLコマンドを生成する

$ python manage.py makemigrations polls
$ python manage.py sqlmigrate polls 0001

対話シェル

$ python manage.py shell

Model

モデル設定・設計

ForeignField
m.CASCADE

Relationships Related object reference Django: モデルフィールドリファレンスの一覧 <- 不完全 モデルフィールドリファレンス

on_delete

Django、on_deleteを使う(django2.0から必須)

models.CASCADE
models.PROTECT
models.SET_NULL
models.SET_DEFAULT
models.SET()
models.DO_NOTHING
AutoField

idに使われる。数字で、自動で1ずつ増える(?)。(参照:https://stackoverflow.com/a/6062240/8776028)

unique

ユニークさを保証するが、shellで試したとき重複するとエラーになってしまうため、使いにくいかも。 idを変更する目的ならいじる必要ない。

*IDを文字列にする

class FooModel(m.Model):
    id = m.CharField(max_length=100, unique=True, primary_key=True)

このようにidを書き換えればいい。

Relationship

多対多関係(Many-to-many)

m.ManyToManyField(RelatedModel)

ManyToManyは.save()してから登録することに注意!

ManyToMany.throughを明示指定すれば任意のモデルをManyToManyのRelationとして使用できる(?)

through Modelの要素でorder_byするベストプラクティス何だろう QuerySetの使い方? Metaで記述する例 #

class ProfileAccount(models.Model):
	pass
	class Meta:
		ordering = ('number',)

多対一

一対一(one-to-one)

m.OneToOneField()

参照される方はsave済みである必要がある。

その他Model.pyを書くときのTips

定義前のモデルを参照

クラス名を文字列で書けば良い

モデル操作

モデルオブジェクトを作成するときの作法

Creating objects

f = FooModel(name='fooo')
f.save()
Player # <- Model
Player.objects.get(id=1)
Player.objects.filter(shard='ea')

クエリ

.filter()の中で使う、多分。

lte (less than or equal)など [](https://docs.djangoproject.com/en/2.0/ref/contrib/gis/geoquerysets/) lte gte

cf. > Consider using the .exists method, for it issues a faster query to your database than if you try to retrieve all the user information with the .get method. And the code gets a little cleaner too

getよりfilter().exists()がいいらしい。

Using Django querysets effectively all()やiterator()についても記述がある。

ループの前にRelatedをあらかじめ取ってくる

select_related(), prefetch_related("creative_set"):

統計分析

Aggregation

[](https://docs.djangoproject.com/ja/2.0/topics/db/aggregation/)

Django-Pandas

[](https://github.com/chrisdev/django-pandas)

View

ディレクトリ設計

簡易

def index(request, ):
    return HttpResponse("Hello world")
urlpatterns = [
    path('', views.index, name='index'),
]
Method view ?で部分的にアップデートする方法

https://stackoverflow.com/a/4674127/8776028

def my_view(request, id): 
    instance = get_object_or_404(MyModel, id=id)
    form = MyForm(request.POST or None, instance=instance)
    if form.is_valid():
        form.save()
        return redirect('next_view')
    return render(request, 'my_template.html', {'form': form}) 

Class View

ListView, DetailView Generic detail views

CreateView, DeleteView, EditView, FormView クラスベースのビューでフォームを扱う

extra_contextは簡易に定義できるものの,urlパラメータを利用したオブジェクトを渡そうとするとselfが必要になる.そこで次のリンクを利用する.

https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-display/#adding-extra-context

Template

HTML

[](https://docs.djangoproject.com/ja/2.0/ref/templates/builtins/) [](https://docs.djangoproject.com/ja/2.0/ref/templates/language/#template-inheritance)

Form

Formクラスを使う。(使わなくてもいいかもしれないが) タグの編集がめんどくさい。

q = forms.CharField(label='search', 
                    widget=forms.TextInput(attrs={'placeholder': 'Search'}))

cf. 公式 one more

値を取り出して使う方法 仮に使わなかった場合、どうやって値を取り出すのか不明。

if form.is_valid():
      subject = form.cleaned_data['subject']

cf.

フォームのPOST先は自動で元のViewだが、actionで指定することもできるらしい? cf.

Submitボタンはないので普通に書いていいっぽい。 cf.

URL

DetailsViewなどを使いたい時、URLではpkまたはslugしか受け付けてもらえない。

cf. What is a slug in dnango モデルにslugを加える必要がありそう。

デバッグ

データベースをデバッグするときの一連の操作

mv db.sqlite3 db.sqlite3.bak
python manage.py migrate --run-syncdb
python manage.py shell
from vainlab.models import Player
from vainlab.vain_api import VainAPI
v = VainAPI()
v.player_matches('ea', 'Qiuqiu')

SQL文を確認する! reference

import logging
log = logging.getLogger('django.db.backends')
log.setLevel(logging.DEBUG)
log.addHandler(logging.StreamHandler())

デプロイ

WSGI

[](https://docs.djangoproject.com/ja/2.0/howto/deployment/wsgi/) よくわからん。

uWSGI

uwsgi これだっ。

static

$ python manage.py collectstatic

dhireクトリ構成

$ tree
.
├── db.sqlite3
├── gitshell
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── settings.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── wsgi.cpython-36.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── listter
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
└── manage.py
comments powered by Disqus