Djangoのメモ。
Django
導入
ラップトップでやったら簡単に同じ環境を作れた。すごい。
mkdir djangoApp
python3 -m venv djangoApp # 仮想環境作成
cd djangoApp
source bin/activate # 有効化
pip3 install django # 仮想環境にインストールされる
プロジェクト作成
django-admin startproject djangoApp
サーバー起動
manage.pyの配置されたディレクトリで、
python3 manage.py runserver
localhost:8000にアクセスする。
タイムスタンプ
from django.utils import timezone
class Log(models.Model):
regist_date = models.DateTimeField(default=timezone.now)
from django.utils import timezone
をインポートして
default=timezone.now
これでレコード登録時の日本時間が保存されます。
日付
datetime → 書式化文字列
>>> import datetime
>>> now = datetime.datetime.now()
>>> now.strftime("%Y/%m/%d %H:%M:%S")
'2012/01/01 20:29:39'
フィールドの初期値
Class Post(models.Model):
title = models.CharField(default='タイトル')
DBの初期化
初期設定
python manage.py makemigrations django_test
python manage.py migrate
python manage.py createsuperuser
モデルのテンプレ
class Cooking(models.Model):
id = models.AutoField(primary_key=True)
register_time = models.DateTimeField(default=timezone.now) # 登録ボタンが押された時刻
cooking_time = models.DateTimeField() # 調理した時刻(フォーム入力)
discard_time = models.DateTimeField(null=True, blank=True) # 廃棄ボタンが押された時刻
num = models.PositiveIntegerField()
product = models.ForeignKey(
'Product',
on_delete=models.CASCADE)
データに沿ったselectを出す方法
例えば商品テーブルに登録されているものすべてを名前フィールドで出して、idで値を調理テーブルに入れるようなときだ。
class FF_Form(ModelForm):
class Meta:
model = Cooking
fields = ["product"]
num = IntegerField()
cooking_time = DateTimeField()
などとする。
ポイントは、外部キーになっているフィールドを参照すること。
ここでは、商品テーブルではなく、調理テーブルのproductを参照する。
さらに、このままではobjectのコード?が出てきて何がなにやらわからないので、model.pyの
class Job(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
job = models.CharField(max_length=64, blank=True)
def __str__(self):
return self.job
defstrを追加して、名前を返すようにすると、わかりやすくなる。
格納時の注意
cooking = Cooking.objects.create(
product_id=request.POST['product'],
num=request.POST['num'],
cooking_time=request.POST['cooking_time'])
cooking.save()
product_idに注目。POSTされる値はproductだが、格納されるのはproductになる。
これは、フォームがモデルからデータを取ってくるときに外部キーのフィールドがproductであるため。
モデルでは、外部キーでも_idがつかない。
フォームの初期値の設定
views.pyにて、
initial_value = {
'cooking_time': now
}
として、
form = ff_form(request.POST, initial=initial_value)
とする。
自作フィルタの追加方法
アプリケーション直下(models.pyとかあるところ)に、templatetagsディレクトリを作成する。
init.pyを作成し、test_tag.pyなどを作成し、中身を
from django import template
register = template.Library()
@register.filter(name="multiplie")
def multiplie(value, args):
return value * args
のようにする。あとはテンプレート内で、
{% load app_tag %} // 作成したファイル名を記述
{{ review.score | mulitiplie:20}}
初期データ投入
アプリケーション直下にfixturesディレクトリを作成する。
中にinitial.json(なんでもいい)を作成し、以下のように記述。
[
{
"model": "django_test.Product",
"pk": 1,
"fields": {
"title": "おはよう"
}
},
{
"model": "app名.モデル名",
"pk": 2,
"fields": {
"title": "こんにちは"
}
}
]
そして、
python manage.py loaddata initial.json
time.time()でタイムゾーンが変わる問題
datetimeではちゃんと表示できているのに、time()をするとタイムゾーンが変わってしまう。
djangoのテンプレートでは勝手に変換してくれるが、time()では変換がなくなる。
仕方ないので9時間足して対応した。
editの例
get・postによって処理を分ける。editとupdateは同じメソッドに書く。
def discard_post(request):
if request.method == 'POST':
cooking = get_object_or_404(Cooking, id=request.POST['id'])
form = DiscardForm(request.POST)
if form.is_valid():
cooking.discard_num = form.cleaned_data['discard_num']
cooking.save()
return redirect(to='/ff_form')
else:
cooking = get_object_or_404(Cooking, id=request.GET['id'])
form = DiscardForm({
'discard_num': cooking.discard_num,
'id': cooking.id
})
d = {
'form': form,
}
一部だけhiddenにする例
class DiscardForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['id'].widget = forms.HiddenInput()
class Meta:
model = Cooking
fields = ['id']
discard_num = IntegerField(label='廃棄個数')
id = CharField()
クエリ条件生成の例
cookings = Cooking.objects.exclude(cooking_time__gt=today).filter(discard_num__exact=None)
ダミーカラムを非表示にする
dataTable.addRows([
/* 全カラム表示用。*/
{% for product in products %}
[ '{{product.name}}',
'',
'opacity: 0',
new Date({{now | conv_dummytime | conv_graph}}),
new Date({{now | conv_dummytime | conv_graph}}),
],
{% endfor %}
このようにすれば、非表示になる。線は見えないものの一応あって、時間が重なると2列になる。
ダミーを現在時にすると重なり、離れすぎるとグラフがおかしくなるので、12時間後にした。
現在時ライン
コピペで動作せず苦労したが、結局divのidをtimelineとして、packages名で揃えたことでできるようになった。よくわからない。
最初はコンテナ名がexample5.1,package名がtimelineだった。
これをどちらもtimelineにした。
コンテナとpackage名なので、たぶん指し示す位置が異なるのだろう。
article/django.txt · 最終更新: 2020/07/22 17:05 (外部編集)