__unicode__書くの面倒。
問題
- djangoのモデルのデフォルトの表示がしょぼい
- オブジェクトの持つフィールドの値が分かんない。
- __unicode__メソッドを自分で書く必要がある。
- モデル毎に__unicode__を定義したくない。
- 面倒くさい
- デコレータとかでどうにかならない?
- でも、__unicode__を定義したモデルでは、そちらを使いたい。
- デコレータで__unicode__を上書きしたくない。
inspectableというデコレータを作成してみた*1
inspectable
こうやって使う。
defaultで__unicode__が定義される。
@inspectable class Foo(models.Model): pass
定義された__unicode__は以下の機能を持っている。
- 全部のフィールドを表示する
なので、python manage.py shellなどでどんな値が入っているのか調べやすい。
__unicode__が定義されているとinspectableは単に無視する(何もしない)
@inspectable class Bar(models.Model): name = models.CharField(max_length=255) def __unicode__(self): #こちらが優先される。 return u"%s" % self.name
まだ途中だけれど使用例。
# -*- coding:utf-8 -*- ## moduleのpath設定していないため import sys sys.path.append(".") from common.misc.inspect import inspectable #これ使っている。 ### sample ## ここから下は、django アプリを使わずにdjango.db.modelsのクラスを使うためにちょっとおまじないを加えてる。 from django.conf import settings settings.configure() import django.db.models as models import types import sys ## ここらへんおまじない _K = "_.sample.models" sys.modules[_K] = types.ModuleType(_K) @inspectable class Item(models.Model): is_soldout = models.BooleanField(default=False) __module__ = _K # models.Base.newをごまかすため class Meta: abstract = True def __unicode__(self): return u">_< %s: %s" % (self.__class__.__name__, self.is_soldout) @inspectable class Author(models.Model): __module__ = _K # models.Base.newをごまかすため name = models.CharField(max_length=255) @inspectable class Book(Item): __module__ = _K # models.Base.newをごまかすため title = models.CharField(max_length=255) author = models.ForeignKey(Author, null=True) ### 利用 bm = globals()["Item"]() print bm print Item(is_soldout=True) print Book(is_soldout=True, title="hoo") author = Author(name="fo") author = Author(name=u"カルピス") print Book(title="hoo", author=author)
出力結果
# python ~/myproject/django-model-inspect/sample.py >_< Item: False >_< Item: True Book: is_soldout = True title = hoo author = None Book: is_soldout = False title = hoo author = Author: name = カルピス
追記
_Kなど書いていたのは単なるおまじないです。これは実際のコードではまったく必要ありません。
おまじないを着けていたのは、django.db.modelsのクラスを使うのにdjangoアプリケーションを作るのが面倒だったからです。
これはどういうことかというと,
python manage.py startapp foo
vim foo/models.py #ここでmodelを定義(普通は)
というのがめんどうだったからです。おまじないを書いたのは、これを単にpythonスクリプトと同様の形式で呼びたかったからです。
単なる横着です。以下のおまじないを含むコードは、その後とおまじないを含まないコードと対応します。
(そして、このおまじないは実際のコードではまったく必要ありません。)
横着のためのおまじないを含んだコード
from django.conf import settings settings.configure() import django.db.models as models import sys _K = "_.sample.models" sys.modules[_K] = types.ModuleType(_K) class Item(models.Model): is_soldout = models.BooleanField(default=False) __module__ = _K # models.Base.newをごまかすため def __unicode__(self): return u"s: %s" % (self.__class__.__name__, self.is_soldout)
実際に必要なコード(普通はこちらで十分)
import django.db.models as models class Item(models.Model): is_soldout = models.BooleanField(default=False) def __unicode__(self): return u"%s: %s" % (self.__class__.__name__, self.is_soldout)