アドベントカレンダーに空白があるので・・・
- Django 1.10.4
- Python 3.5.2
この記事の内容
DjangoではForm関係のAPIは割と手厚いのですが、一つのフォームの中で複数のモデルを編集しようとすると、急に面倒度が上がります。
なので、モジュールを使いながら手早くその辺のことができるようにします。
前の記事の続きのようなものです。
インストールするモジュール
pip install django-extra-views
使い方
django extra viewsはフォームクラスを使わなくても行けるので、そうします。
CreateView
モデル
models.py
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=255)
age = models.IntegerField(default=25) # 25歳に戻りたい
class Car(models.Model):
owner = models.ForeignKey(Person)
color = models.CharField(max_length=10)
views.py
views.py
from extra_views import CreateWithInlinesView, InlineFormSet
class CarInlineFormSet(InlineFormSet):
model = Car
fields = ("color", )
can_delete = False # create view では削除不要
class PersonCarCreateFormsetView(CreateWithInlinesView):
model = Person
fields = ("name", "age") # self.model の fields
inlines = [CarInlineFormSet, ]
template_name = "person_formset.html"
success_url = "/"
テンプレート
person_formset.html
{% extends "base.html" %}
{% block content %}
<form method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
{# インラインはinlinesという変数にリストで入っている #}
<p>Car Color</p>
<table>
{% for form in inlines %}
{{ form.as_table }}
{% endfor %}
</table>
<button type="submit">save</button>
</form>
{% endblock %}
UpdateView
モデル
同じ
views.py
views.py
from extra_views import InlineFormSet, UpdateWithInlinesView
class CarInlineFormSetCanDelete(InlineFormSet):
model = Car
fields = ("color", )
can_delete = True
class PersonCarUpdateFormsetView(UpdateWithInlinesView):
model = Person
fields = ("name", "age")
inlines = [CarInlineFormSetCanDelete, ]
template_name = "person_formset.html"
success_url = "/"
テンプレート
同じ
まとめ
なかなか便利。
追記 2017-09-27
as_table以外での表示の仕方
普通に書いていると、インラインの方を table.name
のように書きたくなる。
ちょっとはまったが、
template.html
{% for inline in inlines %}
{% for line in inline %}
{{ line.name }}
{% endfor %}
{% endfor %}
のように、二重ループすればよい。
inlines
には複数のインラインモデルが設定されているためだと思われる。
追記ここまで