このページでは、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つではないので注意してください。
Contents
__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=1
の Student
モデルクラスのインスタンスをデータベースから取得し、その取得したインスタンスをそのまま 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=1
の Student
モデルクラスのインスタンスで name
が 'YamadaHanako'
に設定されている場合、先ほどと同じ name_view
が実行された場合でも、print
で出力される文字列は下記のようなものに変化することになります。
YamadaHanako
要は、インスタンスを出力する際に、__str__
メソッドが実行され、このメソッドの return
するデータが出力されるようになります。上記の場合は self.name
を return
しているため、インスタンスの name
に設定されているデータが出力されるようになるというわけです。
特にプライマリーキーが id
となっている場合、インスタンスを出力する際に id
しか表示されないのでインスタンスの内容が分かりにくいです。その表示内容を分かりやすくするために __str__
が活躍することになります。
__str__
メソッドの定義の仕方
続いて __str__
メソッドの定義の仕方について説明します。
といっても __str__
メソッドの定義の仕方は簡単で、モデルの定義の中に名前が __str__
のメソッドを定義してやれば良いだけです。ただし、引数は self
とし、必ず return
を行う必要があります。そして、return
するデータはインスタンス出力時に出力したい文字列である必要があります。
def __str__(self):
return 文字列のデータ
__str__
メソッドが return
をしなかった場合や、文字列以外のデータを return
するような場合、インスタンスの出力時に下記のような例外が発生することになるので注意してください(type
の後ろ側には return
したデータの形が表示されます)。
__str__ returned non-string (type NoneType)
文字列さえ return
してやれば良いので、下記のように連結して生成した文字列などを return
しても良いことになります。
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__
メソッドの return
したデータが表示されるようになるため、各項目の表すインスタンスが分かりやすくなります。
ただし、管理画面で管理可能なモデルは、デフォルトでは Group
と User
のみとなっており、自身で定義したモデルを管理する場合は 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__
メソッドを定義した場合、前述でも示した下図のような一覧が表示されるようになり、どの項目がどのインスタンスを表しているかが分かりやすくなります。
フォームでのインスタンス表示
また、Django のフォームでは「インスタンスの選択フィールド」を持たせることができます。この選択フィールドにはインスタンスが選択肢として表示されることになりますが、この選択肢として表示される文字列はインスタンスの出力結果となります。
例えばフォームに CharField
を持たせた場合、文字列入力用のフィールドを表示して文字列の入力をユーザーから受け付けることが可能となります。
これと同様に、ModelChoiceField
をモデルに持たせた場合、引数で指定したクエリーセットに含まれるインスタンスを選択肢とするプルダウンメニューが表示されるようになります。
これにより、ユーザーがフォームから特定のインスタンスを選択することができるようになるのですが、前述の通り、このプルダウンメニューに表示される選択肢の項目はインスタンスそのものの出力結果が表示されることになります。
そのため、このプルダンメニューに表示される選択肢の項目は、__str__
メソッドを定義していない場合、下の図のようなユーザーにとって意味不明な文字列として表示されることになります。
それに対し、__str__
メソッドを定義している場合、下の図のようにユーザーにも理解してもらえる文字列として表示することが可能となります。
スポンサーリンク
まとめ
このページでは、Django のモデルにおける __str__
メソッドについて解説を行いました!
__str__
メソッドはモデルのインスタンスを出力した際に表示される文字列を決めるためのメソッドです。このメソッドを定義しない場合、インスタンスを出力した際には下記の形式で文字列が表示されることになります。はっきりいって、この形式で文字列が表示されてもユーザーにはインスタンスの内容が理解できません。
モデル名 object (プライマリーキーの値)
それに対し、__str__
メソッドを定義しておけば、インスタンス出力時に表示される文字列が __str__
メソッドの return
する文字列に置き換えられることになります。したがって、__str__
メソッドの return
する文字列を分かりやすいものにしてやれば、ユーザーにもインスタンスの内容が理解しやす文字列が表示されるようになります。
もちろん、お試しでウェブアプリを開発している場合や、自分自身でしか利用しないウェブアプリを開発している場合は別に良いのですが、他の人に利用してもらうことを目的としているウェブアプリであれば __str__
メソッドは定義しておくに越したことはないと思います。