【Django】class Meta(メタクラス)を解説

プログラミング
Masa
Masa

こんにちは!Masaです。

今回はpythonのメタクラスについて調べたのでまとめます!

この記事でわかること
  • 一般的なメタクラスについて
  • Pythonのメタクラスについて

メタクラスとは

まずは一般的なメタクラスについて見ていきましょう。

オブジェクト指向プログラミングにおいてメタクラスは、インスタンスがクラスとなるインスタンスのことである。通常のクラスがそのインスタンスの振る舞いを定義するように、メタクラスはそのインスタンスであるクラスを、そして更にそのクラスのインスタンスの振る舞いを定義する。
(wikipediaより)

つまり、メタクラスはクラスとそのインスタンスの振る舞いを定義する機能を持ちます。

上記のメタクラスは一般的なメタクラスを指していますが、Python・Djangoのメタクラスも例外なく同様の機能を持ちます

ただ文章ではイメージが付きにくいので、例と合わせて見てみましょう・

メタクラスの例

このサイトで扱っているDjangoで例を見ていきましょう。

以下のDjangoのモデルがあるとします。
あるホテルの朝食のモデルです。

class Morning(models.Model):
    date = models.DateTimeField(verbose_name='日付')
    staple = models.CharField(verbose_name='主食', max_length=10)
    main = models.CharField(verbose_name='主菜', max_length=10)
    side = models.CharField(verbose_name='副菜', max_length=10)
    soup = models.CharField(verbose_name='スープ', max_length=10)
    
    def __str__(self):
        return self.date

このままだとDjangoの管理画面では”Morinings”という名前で表示されます。

Django管理画面①

作成した人はわかりますが、管理者が何人もいたりするとこの表示名はわかりにくいですよね。

そこで”Morings”を”朝食”に変えたいと思います。
ここで使用するのがメタクラスです。

以下のようにメタクラスを追加します。

class Morning(models.Model):
    date = models.DateField(verbose_name='日付')
    staple = models.CharField(verbose_name='主食', max_length=10)
    main = models.CharField(verbose_name='主菜', max_length=10)
    side = models.CharField(verbose_name='副菜', max_length=10)
    soup = models.CharField(verbose_name='スープ', max_length=10)

    # メタクラス
    class Meta:
        verbose_name_plural = '朝食'
    
    def __str__(self):
        return str(self.date)

これで”Mornings”が”朝食”に変わりました。
”verbose_name_plural”は管理画面上でのモデルの表示名を指定できます(語尾に”s”なし)

Django管理画面②

”verbose_name_plural”で管理画面上の表示名を変えることはMorningsモデルクラスの機能自体を定義しているわけではありません

しかし管理画面での表示を変えるというクラスの機能自体には関係ない定義をメタクラスで行いました。
つまり、Morningクラスの振る舞いをメタクラスで定義したということになります。

ひとつの例ですが、これがメタクラスで行える具体例となります。

まとめ

今回の記事ではメタクラスの意味と具体例を用いた実際の使い方を見ていきました。

メタクラスは、クラスとそのインスタンスの振る舞いを定義する機能を持ちます。

実際にDjangoでは管理画面上でのモデルクラスの表示名を変えたりできるなど、クラス自体の機能とは関係ないですが、それ以外の便利な機能を持たせることができました。

今後よりわかりやす表現や解説がありましたらアップデートしていきます。

コメント

タイトルとURLをコピーしました