概要
DjangoのORMではvalues_list
メソッドがありますが、これの引数にはflat
があります。
本記事ではこのflat
の意味と大事になるケースを紹介します。
サンプルコード
以下記事にて、以前紹介した下記のコードでflat=True
を使っていたのですが、改めて使い方を確認。
【Python】終端記号を考慮して100文字までカットするコード
このコードでは、PuncCd
モデルから取得した複数の終端記号の中で該当する最後のものにより文章を区切っています。
from xxx.models import PuncCd
def truncate_comment_at_last_punc(comment):
last_punc_location = None
punc_cd_values = PuncCd.objects.values_list('punc', flat=True)
for punc_value in punc_cd_values:
location = comment.rfind(punc_value)
if location == -1:
continue
if last_punc_location is None or location > last_punc_location:
last_punc_location = location
truncated_comment = None
if last_punc_location is not None:
truncated_comment = comment[:last_punc_location + 1]
return truncated_comment
comment = "ここにコメントが入ります"
comment_100 = truncate_comment_at_last_punc(comment[:100])
上記で、もしflat=True
としない場合、以下のエラーになります。
'must be str, not tuple'
なぜかというと、rfind
メソッドは文字列に対して動作するため、タプルではなく文字列を渡す必要があります。しかし、values_list
でflat=True
を使用しない場合、punc_cd_values
はタプルのリストであり、タプルは文字列ではないため、rfind
メソッドがタプルに対して呼ばれると 'must be str, not tuple'
エラーが発生するのです。
flat=True
とは?
Django ORM(Object-Relational Mapping)のvalues_list
メソッドに対する引数。
この引数を指定することで、values_list
メソッドはクエリセットから取得したデータを平らな(フラットな)リストとして返します。
リストとして扱いたい場合に活用できます。
例としては、以下のようになります。
flat=True
の場合
country = Country.objects.values_list("country_name", flat=True)
print(country)
# 出力
# <QuerySet ['日本', 'スペイン', 'ドイツ', 'コスタリカ']>
flat=False
の場合
country = Country.objects.values_list("country_name", flat=False)
print(country)
# 出力
# <QuerySet [('日本',), ('スペイン',), ('ドイツ',), ('コスタリカ',)]>
上記のように、False
にするとそれぞれのオブジェクトがタプルの要素となっていることがわかります。
各値をタプル内にラップされたリストにしたい時は、False
が使えます。この場合は、値にアクセスするためにインデックスを使用する必要があります。
逆に、単純な値のリストが得たい場合はTrue
を使うと良いでしょう。
True
にすることで、各カラムの値がリストの要素として一括りになります。