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名なので、たぶん指し示す位置が異なるのだろう。