Djangoで、「保存してもう一つ追加」「保存して編集を続ける」機能の作成

Python - Django
2018年11月19日2:44に更新(約9時間前)
2018年11月7日14:26に作成(約11日前)

旧ブログ移行記事です。

概要


Djangoで、保存してもう一つ追加保存して編集を続ける機能を作成します。管理サイトにある機能ですが、通常のページにも簡単につけることができます。

models.py

どんなモデルを使おうと関係ないのですが、今回は以下のようなシンプルなモデルを使います。

from django.db import models


class Post(models.Model):
    title = models.CharField('タイトル', max_length=30)
    text = models.TextField('本文')

    def __str__(self):
        return self.title

post_form.html

{% extends 'app/base.html' %}
{% block content %}
{{ form.non_field_errors }}
<form action="" method="POST">
    <table class="table">
        <tbody>
            {% for field in form %}
                <tr class="warning">
                    <td>{{ field.label_tag }}</td>
                    <td>{{ field }}</td>
                    <td>{{ field.errors }}</td>
                </tr>
            {% endfor %}
        </tbody>
</table>
    {% csrf_token %}
    <button class="btn btn-primary" type="submit">送信</button>
    <button class="btn btn-primary" type="submit" name="save_and_add">保存してもう一つ追加</button>
    <button class="btn btn-primary" type="submit" name="save_and_edit">保存して編集を続ける</button>
</form>
{% endblock %}

重要なのは以下の3行です。type="submit"な要素に、name="種類"といった感じで設定しておきます。Django管理サイトも、これと似た書き方をして機能を実装しています。

    <button class="btn btn-primary" type="submit">送信</button>
    <button class="btn btn-primary" type="submit" name="save_and_add">保存してもう一つ追加</button>
    <button class="btn btn-primary" type="submit" name="save_and_edit">保存して編集を続ける</button>

views.py

from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.views import generic
from .models import Post


class Index(generic.ListView):
    model = Post


class Create(generic.CreateView):
    model = Post
    fields = '__all__'
    success_url = reverse_lazy('app:index')

    def form_valid(self, form):
        post = form.save()

        # 保存してもう一つ追加ボタンのとき
        if 'save_and_add' in self.request.POST:
            return redirect('app:create')

        # 保存して編集を続けるボタン
        elif 'save_and_edit' in self.request.POST:
            return redirect('app:update', pk=post.pk)

        return redirect('app:index')


class Update(generic.UpdateView):
    model = Post
    fields = '__all__'
    success_url = reverse_lazy('app:index')

    def form_valid(self, form):
        post = form.save()

        # 保存してもう一つ追加ボタンのとき
        if 'save_and_add' in self.request.POST:
            return redirect('app:create')

        # 保存して編集を続けるボタン
        elif 'save_and_edit' in self.request.POST:
            return redirect('app:update', pk=post.pk)

        return redirect('app:index')

submitボタンを押すと、そのボタンのname属性の値がPOSTで送信されます。それを利用し、どのボタンでサブミットされたかを判断できます。

        # 保存してもう一つ追加ボタンのとき
        if 'save_and_add' in self.request.POST:
            return redirect('app:create')  # 新規作成ページにリダイレクト

        # 保存して編集を続けるボタン
        elif 'save_and_edit' in self.request.POST:
            return redirect('app:update', pk=post.pk)  # そのデータの更新ページへリダイレクト

他にも、以下のようにvalue属性を利用する方法もあります。

(HTML)
<button class="btn btn-primary" type="submit" name="kind" value="add">保存してもう一つ追加</button>
...
...
(ビュー)
if self.request.POST.get('kind') == 'add':
    value="add"なボタンを押した際の処理...

記事にコメントする