こんばんはエンジニアの眠れない夜です。
Djangoで開発をしていてモデルのフィールド名に_アンダースコアをつけて後悔した話です。
結論から言うとタイトルの通りで、「モデルのフィールド名は_アンダースコアから始めない方が良い」です。
_アンダースコアで始めないほうがいい理由
それを話していく前にまずはどんなものを作ってしまったかをご紹介します。
開発をしていて私はこんなフィールドを作りました。
class Message(models.Model):
create_at = models.DateTimeField(default=timezone.now)
_from = models.ForeignKey(User)
to = models.ForeignKey(User)
body = models.TextField()
(読みづらいので細かい設定は省略しています)
何をしたいかというとMessageモデルにfromとtoというフィールドをもたせてUserモデルに関連付けてメッセージをやり取りをする機能を作りたかったのです。
そこでfrom
はpythonの予約ごと重複するので_from
というpythonでローカル変数を指定するときなどに使う方法で名前をつけてみました。
しかし、これだとテンプレートで呼び出す時に
Message._from
とやると下記のエラーが出て怒られます。
Variables and attributes may not begin with underscores django template
アンダースコアから始まる変数と属性はダメ。ってことですね。
そこで、調べてみるとテンプレートフィルターを使えば回避できるよ的なことが紹介されていました。
ただ、この方法だとdict型から取り出す分にはいいのですが、Modelに対して実行すると取ってきたモデルのフィールドにはアクセスできません。
message|get:"_from".email # エラーが出る
キーを使って返ってくるフィールドを選択できるようにテンプレートタグを作ってみました。
@register.filter(name='from')
def get(message,key):
if key=='pk' or key=='id':return message._from.id
if key=='email':return message._from.email
return message._from.username
しかし、毎回こんなふうに書くのは面倒です。
message|from:"email"
UserがImageFiledを持っていてその先のフィールドにアクセスしたい時はこんな書き方ではアクセスさせてくれません。
message|from:"image".url
こんなことをするくらいなら初めからモデルのフィールド名にアンダースコアから始まる名前をつけない方がメンテが楽です。
ちなみに、アンダースコアをフィールド名の後ろにつけると
→from_
base.Message.from_: (fields.E001) Field names must not end with an underscore.
フィールド名はアンダースコアで終わるのはダメ。と怒られます。
と、いうことで、、、
まとめと妥協案
「Djangoのモデルのフィールド名は_アンダースコアから始めない方が良い」ということです。
回避策としていいなと思ったのは関連モデルの名前を接尾語として足すのが今のところ一番いい方法ではないかと思います。
from_user
これなら予約ごとぶつかる心配もないですし、フィールドの意味も分かりやすい!
`from_user.id`
`from_user.email`
`from_user.username`
うん。わかりやすい。いっそのことto
もto_user
にしてしまった方がいいのではないかという気がしてきました。
`to_user.id`
`to_user.email`
`to_user.username`
他にもいい方法があれば是非コメントを頂けると嬉しいです。
※ 間違っているところなどありましたらご指摘いただけますと幸いです。
[…] 【Django】モデルのフィールド名は_アンダースコアから始めない方が良い […]