【Django】モデル(Model)の__str__メソッドとは?

モデルの__str__メソッドの説明ページアイキャッチ

このページにはプロモーションが含まれています

このページでは、Django におけるモデルの __str__ メソッドについて解説していきます。

参考書やウェブページ等で示されているモデルの例では、下記のように __str__ メソッドが定義されていることが多いです。

モデルの定義例
from django.db import models

class Student(models.Model):
    name = models.CharField(max_length=256)

    def __str__(self):
         return self.name

この __str__ メソッドの意味合いについて説明していきたいと思います。ちなみに、__str__str をアンダーバー2つで囲う形で記述します。アンダーバー1つではないので注意してください。

__str__ メソッドとは?

__str__ メソッドとは、モデルのインスタンス出力時の出力文字列を決定するためのメソッドとなります。

__str__メソッドの説明図

インスタンス出力時の出力文字列を決定する

Python では、例えば print 関数で文字列を標準出力に出力することができます。この際には、print 関数の引数に指定した文字列がそのまま出力されることになります。

同様に、モデルのインスタンスに関しても出力を行うことが可能です。ですが、モデルのインスタンスを出力した際には何が出力されることになるのでしょうか?

__str__ メソッドが定義されていない場合、モデルのインスタンスを出力した際には、下記の形式の文字列が出力されることになります。

モデル名 object (プライマリーキーの値)

この形式での出力を行うのではなく、もっと分かりやすい文字列の出力を実現するために定義するのが __str__ メソッドで、このメソッドを定義することで、モデルのインスタンスを出力した際の出力文字列を自身で決めることができるようになります。

スポンサーリンク

__str__ メソッドの効果

例えば、下記のように models.py を作成し、

モデルの定義例
from django.db import models

class Student(models.Model):
    name = models.CharField(max_length=256)

さらに、下記のように views.py を作成したとします。下記の name_view では、id=1Student モデルクラスのインスタンスをデータベースから取得し、その取得したインスタンスをそのまま print で出力しています。

インスタンスの表示
from .models import Student

def name_view(request):

    student = Student.objects.get(id=1)
    print(student)

そして、上記の views.py における name_view が実行された際、print での出力結果は次のようになります。どのモデルのインスタンスであるかは分かりますが、このインスタンスがどのような内容のものかは分かりにくいですね…。

Student object (1)

それに対し、下記のようにモデルの定義を変更して __str__ メソッドを追加した場合、

モデルの定義例
from django.db import models

class Student(models.Model):
    name = models.CharField(max_length=256)

    def __str__(self):
        return self.name

id=1Student モデルクラスのインスタンスで name'YamadaHanako' に設定されている場合、先ほどと同じ name_view が実行された場合でも、print で出力される文字列は下記のようなものに変化することになります。

YamadaHanako

要は、インスタンスを出力する際に、__str__ メソッドが実行され、このメソッドの return するデータが出力されるようになります。上記の場合は self.namereturn しているため、インスタンスの name に設定されているデータが出力されるようになるというわけです。

特にプライマリーキーが id となっている場合、インスタンスを出力する際に id しか表示されないのでインスタンスの内容が分かりにくいです。その表示内容を分かりやすくするために __str__ が活躍することになります。

__str__ メソッドの定義の仕方

続いて __str__ メソッドの定義の仕方について説明します。

といっても __str__ メソッドの定義の仕方は簡単で、モデルの定義の中に名前が __str__ のメソッドを定義してやれば良いだけです。ただし、引数は self とし、必ず return を行う必要があります。そして、return するデータはインスタンス出力時に出力したい文字列である必要があります。

__str__の定義
def __str__(self):
    return 文字列のデータ

__str__ メソッドが return をしなかった場合や、文字列以外のデータを return するような場合、インスタンスの出力時に下記のような例外が発生することになるので注意してください(type の後ろ側には return したデータの形が表示されます)。

__str__ returned non-string (type NoneType)

文字列さえ return してやれば良いので、下記のように連結して生成した文字列などを return しても良いことになります。

__str__の定義例
def __str__(self):
    return str(self.id) + ' : ' + self.name

もちろんスライスなども利用できますので、インスタンス出力時に分かりやすい文字列が表示されるよう、return するデータを工夫すると良いと思います。

__str__ メソッドが利用されるタイミング

ここまで print の例で __str__ メソッドの効果を示してきましたが、実際 Django で開発するウェブアプリで print を行う機会はほとんどないと思います。では、__str__ メソッドを定義する必要がないかというと、そういうわけではなく、様々なタイミングでインスタンスの出力が行われ、その際に __str__ メソッドが実行されることになります。

では、具体的に、どんな時に __str__ メソッドが実行されるのか?

この点について解説していきます。

スポンサーリンク

テンプレートへのインスタンスの埋め込み

Django ではテンプレートファイルを利用して HTML を生成することになります。さらに、テンプレートファイルには変数が埋め込み可能です。この変数の埋め込みは、テンプレートファイルに {{ 変数名 }} を記述することで実現できます。これにより、{{ 変数名 }} の部分が HTML 生成時に 変数名 の変数の値に置き換えられることになります。

そして、この変数にはモデルのインスタンスを指定することも可能です。そしてこの場合、HTML 生成時に __str__ メソッドが実行され、__str__ メソッドの return したデータが埋め込まれることになります。

例えば、ビューで下記のようなコンテキストを用意し、

コンテキストの用意
student = Student.objects.get(id=1)
context = {
    'instance' : student
}

テンプレートファイルの中に下記を記載しておけば、テンプレートファイルの中に __str__ メソッドの return したデータが埋め込まれて HTML が生成されることになります。

変数の参照
{{ instance }}

管理画面でのインスタンス表示

また、Django では管理画面が標準で用意されており、この管理画面から各モデルのインスタンスの管理(追加・変更・削除など)を行うことが可能です。

この管理画面では各モデルのインスタンス一覧を表示することが可能ですが、この一覧の各項目名としてはインスタンスの出力結果が表示されることになります。したがって、__str__ メソッドを定義しなかった場合は、前述の通り下図のような形式の文字列が表示されることになり、各インスタンスの内容が非常に分かりにくいです。

管理画面におけるインスタンスの出力結果(__str__なし)

それに対し、__str__ メソッドを定義しておけば、__str__ メソッドの return したデータが表示されるようになるため、各項目の表すインスタンスが分かりやすくなります。

管理画面におけるインスタンスの出力結果(__str__あり)

ただし、管理画面で管理可能なモデルは、デフォルトでは GroupUser のみとなっており、自身で定義したモデルを管理する場合は admin.py でモデルの登録設定を行う必要があります。例えば、前述で示した Student を管理するのであれば、admin.py を下記のように変更する必要があります。

管理画面への登録
from django.contrib import admin
from .models import Student

admin.site.register(Student)

admin.py を変更した後に管理画面にログインすれば Students のリンクが表示されるようになり、このリンクをクリックすることで Student のインスタンス一覧を表示することができます。そして、この一覧の項目の表示名は 、__str__ メソッドを定義している場合は __str__ メソッドの return する文字列となります。

管理するモデルが追加された様子

例えば、__str__ メソッドの定義の仕方 の最後に示した __str__ メソッドを定義した場合、前述でも示した下図のような一覧が表示されるようになり、どの項目がどのインスタンスを表しているかが分かりやすくなります。

管理画面におけるインスタンスの出力結果(__str__あり)

フォームでのインスタンス表示

また、Django のフォームでは「インスタンスの選択フィールド」を持たせることができます。この選択フィールドにはインスタンスが選択肢として表示されることになりますが、この選択肢として表示される文字列はインスタンスの出力結果となります。

例えばフォームに CharField を持たせた場合、文字列入力用のフィールドを表示して文字列の入力をユーザーから受け付けることが可能となります。

CharFieldがフォームに表示される様子

これと同様に、ModelChoiceFieldをモデルに持たせた場合、引数で指定したクエリーセットに含まれるインスタンスを選択肢とするプルダウンメニューが表示されるようになります。

OneToOneFieldがフォームに表示される様子

これにより、ユーザーがフォームから特定のインスタンスを選択することができるようになるのですが、前述の通り、このプルダウンメニューに表示される選択肢の項目はインスタンスそのものの出力結果が表示されることになります。

そのため、このプルダンメニューに表示される選択肢の項目は、__str__ メソッドを定義していない場合、下の図のようなユーザーにとって意味不明な文字列として表示されることになります。

インスタンス出力結果がプルダウンメニューの選択肢に表示される様子(__str__なし)

それに対し、__str__ メソッドを定義している場合、下の図のようにユーザーにも理解してもらえる文字列として表示することが可能となります。

インスタンス出力結果がプルダウンメニューの選択肢に表示される様子(__str__あり)

スポンサーリンク

まとめ

このページでは、Django のモデルにおける __str__ メソッドについて解説を行いました!

__str__ メソッドはモデルのインスタンスを出力した際に表示される文字列を決めるためのメソッドです。このメソッドを定義しない場合、インスタンスを出力した際には下記の形式で文字列が表示されることになります。はっきりいって、この形式で文字列が表示されてもユーザーにはインスタンスの内容が理解できません。

モデル名 object (プライマリーキーの値)

それに対し、__str__ メソッドを定義しておけば、インスタンス出力時に表示される文字列が __str__ メソッドの return する文字列に置き換えられることになります。したがって、__str__ メソッドの return する文字列を分かりやすいものにしてやれば、ユーザーにもインスタンスの内容が理解しやす文字列が表示されるようになります。

もちろん、お試しでウェブアプリを開発している場合や、自分自身でしか利用しないウェブアプリを開発している場合は別に良いのですが、他の人に利用してもらうことを目的としているウェブアプリであれば __str__ メソッドは定義しておくに越したことはないと思います。

同じカテゴリのページ一覧を表示