Admin actionsを使う4 - ForeignKeyデータを一括更新編
Admin actionsの利用方法
Admin actionsはフラグをたてたり、更新、削除など色々用途はありますが、だいたいBoolenField, CharField やIntegerFieldなどに対しての処理です。
ForeignKeyを対象に出来たら便利だと思いませんか?
仕様
一括更新の手順は以下の通りです。
- 変更するデータを選択します。
- 一括更新のアクションを選択して、実行ボタンをクリック。
- 遷移した画面から変更するデータを選択し、更新ボタンをクリックして処理実行。
model作成
ForeignKeyを含んだmodelを作成します。
models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length = 100)
def __unicode__(self):
return self.name
class Product(models.Model):
category = models.ForeignKey(Category, verbose_name = 'categories')
name = models.CharField(max_length = 100)
price = models.DecimalField(max_digits = 15, decimal_places = 2)
def __unicode__(self):
return self.name
admin作成
ベースのAdminを作成します。
admin.py
from django.contrib import admin
from appname.models import Product
class ProductAdmin(admin.ModelAdmin):
list_display = ('name', 'price', 'category', )
admin.site.register(Product, ProductAdmin)
modelにデータ追加
サンプルデータを追加します。
>>> from appname.models import Product, Category
>>>Category.objects.create(name = 'PC')
>>>Category.objects.create(name = 'Mac')
>>>c1 = Category.objects.get(pk = 1)
>>>c2 = Category.objects.get(pk = 2)
>>>Product.objects.create(category = c1, name = 'HP Mini', price = 100)
>>>Product.objects.create(category = c1, name = 'iPhone', price = 150)
>>>Product.objects.create(category = c2, name = 'MacBook', price = 200)
>>>Product.objects.create(category = c2, name = 'MacBook Air', price = 250)
>>>Product.objects.create(category = c2, name = 'Mac Pro', price = 300)
Change listは以下の通りです。
Admin actionsの作成
まずModelChoiceFieldを利用するためforms.pyを作成します。
forms.py
from appname.models import Category
from django import forms
class CategoryForm(forms.Form):
category = foms.ModelChoiceField(queryset = Category.objects.all())
次にアクションを定義します。
admin.py
from django.contrib import admin
from appname.models import Product
from appname.forms import ProductForm
from django.shortcuts import render_to_response
from django.template import RequestContext
class ProductAdmin(admin.ModelAdmin):
list_display = ('name', 'price', 'category', )
actions = ['set_category_action']
def set_category_action(self, request, queryset):
if 'do_action' in request.POST:
form = CategoryForm(request.POST)
if forms.is_valid():
queryset.update(category = form.cleaned_data['category'])
return
else:
form = CategoryForm()
return render_to_response(
'admin/set_category.html',
{'title': u'Change Category', 'objects': queryset, 'form': form},
context_instance = RequestContext(request))
set_category_action.short_description = u'Set Category'
最後にAdmin site内に表示するtemplateを作成します。
admin/set_category.html
{% extends "admin/base_site.html" %}
{% block content %}
<form action = "" method = "POST">
<input type = "hidden" name = "action" value = "set_category_action">
<input type = "hidden" name = "do_action" value = "yes">
<div>
{{ form.category }}
<input type = "submit" class = "default" style = "float: none" value = "更新">
{{ form.category.errors }}
</div>
<ul>
{% for object in objects %}
<li>
<a href = "{{ obkect.pk }}/">{{ object.name }}</a> - {{ object.category }}
<input type = "hidden" name = "_selected_action" value = "{{ object.pk }}">
</li>
{% endfor %}
</ul>
</form>
{% endblock %}
動作確認
動作させてみます。



