naritoブログ

【お知らせ】
・コメントで質問等をしたが返事が返ってこない場合、私はそれを見落としています。
その場合は再度コメントをするかメールをしてください(toritoritorina@gmail.com)。

・近いうちに新しいブログが作成されます。わーお!

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

約156日前 2018年4月21日3:49
プログラミング関連
Django Python

概要


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

Githubにサンプルコードを置きました

models.py


どんなモデルを使おうと関係ないのですが、views.pyやpost_form.htmlを見た際に混乱しないよう紹介しておきます。
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"なボタンを押した際の処理...