Admin site以外でAdminWidgetsを使う - FilteredSelectMultiple編

便利なwidget

Admin siteを使用したことのある人はわかると思いますが、FilteredSelectMultiple便利です。

これを、Admin site以外でも使いたいと思いませんか?

仕様

  1. ModelFormを利用したアプリケーション
  2. ManyToManyFieldを使用したmodelを作成
  3. ManyToManyFieldはform上ではModelMultipleChoicesFieldとし、
    widgetはFilteredSelectMultipleを使用

model作成

FilteredSelectMultiple Widgetを使うにはManyToManyFieldを含んだmodelを作成します。

models.py

from django.db import models
from django.contrib.auth.models import User

class Tag(models.Model):
    tag = models.CharField(max_length = 10)

    def __unicode__(self):
        return self.tag

class Post(models.Model):
    title = modelsCharField(max_length = 50)
    author = models.ForeignKey(User)
    content = models.TextField()
    post_date = modeld.DateTimeField()
    tags = models.ManyToManyField(Tag)

    def __unicode__(self):
        return self.title

データ追加

Tag modelにデータを追加します。

>>> from appname.models import Tag
>>>t1 = Tag(tag = 'Python')
>>>t1.asve()
>>>t2 = Tag(tag = 'Django')
>>>t2.save()

Form作成

ModelFormを使用してFormを作成します。

forms.py

from django import forms
from django.contrib.admin import widgets  as adminwidgets
from appname.models import Tag, Post

class PostForm(forms.ModelForm):
    tags = forms.ModelMultipleChoicesField(Tags.objects.all(), 
        widget = adminwidgets.FilterSelectMultiple("Tags", False, attrs = {'rows': '10'}))
    post_date = forms.DateTimeField(widget = adminwidgets.AdminSplitDateTime)

    class Meta:
        model = Post

view作成

作成したPostFormクラスを表示できるようにします。

views.py

from appname.forms import PostForm
from django.shortcuts import render_to_response

def viewPost(request):
    postform = PostForm()
    return render_to_response('form.html', {'postform': postform.as_table()})

HTML作成

表示するためのHTMLを作成します。

base.html

<html>
<head>
    <title></title>
    {% block scripts %}{% endblock %}
    {% block css %}{% endblock %}
</head>
<body>
    <H1>Use FilteredSelectMultiple</H1>
    {% block content %}{% endblock %}
</body>
</html>

form.html

{% extends "appname/base.html" %}

{% block scripts %}
<script type="text/javascript" src="/media/js/core.js"></script>
<script type="text/javascript" src="/media/js/getElementsBySelector.js"></script>
<script type="text/javascript" src="/media/js/actions.js"></script>
<script type="text/javascript" src="/media/js/SelectBox.js"></script>
<script type="text/javascript" src="/media/js/SelectFilter2.js"></script>
<script type="text/javascript" src="/media/js/jsi18n.js"></script>
{% endblock %}

{% block css %}
<link rel="stylesheet" type="text/css" href="/media/css/base.css" >
<link rel="stylesheet" type="text/css" href="/media/css/forms.css" />
{% endblock %}

{% block content %}
<body>
    <form action="." method="POST">
    <table>
        {{postform}}
    </table>
    </form>
</body>
{% endblock %}

表示

アクセスすると以下のようになります。

filteredselectmultiple01_01

ただ、Admin siteのCSSを利用してもAdmin siteと同じように表示できていません。
Reuse Django Admin FilteredSelectMultiple Widgetにある"style.css"を参考にして調整してみてください。

twitter 2009-12-09 17:00:10.898635

関連ページ

参照サイト

Recent Updates

URLConf Tip 01 - キャプチャの有無にかかわらず同一のviewで処理する
Markdownの入力補助"wmd"をAdmin siteで使う
ModelFormでfieldのwidgetを変更する
動的なformを作る 6 - Dynamic Inline Admin site編
Formsetsを使う3 - inlineformset_factory編
動的なformを作る 5 - django-dynamic-formset編
Formクラスからメディアを定義する
複数のmodelを結合する 2 - Proxy model編
複数のmodelを結合する 1
ModelFormでfieldの表示順番を変える
Admin siteのwidgetを個別に変更する
formfield_overridesを使ってAdmin siteのwidgetを変更する
Admin siteのlist_displayをカスタマイズする - リンク編
Admin siteのlist_displayをカスタマイズする - 基本編
Admin siteのTextareaの高さを自在に変更する - admin.py編