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='タイトル')
python manage.py flush
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)
例えば商品テーブルに登録されているものすべてを名前フィールドで出して、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
datetimeではちゃんと表示できているのに、time()をするとタイムゾーンが変わってしまう。 djangoのテンプレートでは勝手に変換してくれるが、time()では変換がなくなる。
仕方ないので9時間足して対応した。
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,
}
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名なので、たぶん指し示す位置が異なるのだろう。