作成者/変更者、時刻を追加するDRYな方法
質問
次のようなものがあります。
- 作成日時
- 作成日
- 変更日時
- 修正日
多くのテーブルで非常によくあるパターンでしょう。
1) model.pyで、作成日を自動的に設定することができます(他はできません)。
created_date = models.DateTimeField(auto_now_add=True, editable=False)
2) model.pyで、作成日/変更日(ただし、リクエストコンテキストを持たないので、ユーザー別ではない)を行うことができます。
def save(self):
if self.id:
self.modified_date = datetime.now()
else:
self.created_date = datetime.now()
super(MyModel,self).save()
3) admin.pyで作成/変更日時を設定することもできますが、これは管理者以外の更新に対処できません。
def save_model(self, request, obj, form, change):
if change:
obj.modified_by = request.user
obj.modified_date = datetime.now()
else:
obj.created_by = request.user
obj.created_date = datetime.now()
obj.save()
4) そして最終的には、view.pyで4つすべてを行うことができますが、管理者の更新をカバーすることはできません。
そのため、現実的にはロジックを分散させ、最低でも3 & 4で繰り返す必要があります(または、両方から呼び出されるモデル上のメソッド、これは見逃されます)。
何か良い方法はないでしょうか? (私は数日間python/jangoで作業しているので、明らかに何かを見逃している可能性があります)
- login_requiredのようなものを行うことができますか?
- モデルでリクエストと現在のユーザーにアクセスし、そこにロジックを集中させることは可能か?
どのように解決するのでしょうか?
作成・変更日時はDjangoで扱えるようになったので、以下のように実装できます。
class BaseModel(models.Model):
created_date = models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
これを抽象モデルのベースクラスに追加することで、アプリケーションのすべてのモデルに簡単に追加することができます。
ユーザーを格納するのはより困難です。
request.user
が利用できないので、ユーザーを格納するのはより困難です。SeanOC が言及したように、これは Web リクエストとモデル層との間の関心事の分離です。このフィールドを常に渡しておくか、あるいは
request.user
をスレッドローカルに格納するかです。Django CMS は、彼らのパーミッションシステムにこれを採用しています。
class CurrentUserMiddleware(object):
def process_request(self, request):
set_current_user(getattr(request, 'user', None))
そして、ユーザートラッキングは別の場所で行われます。
from threading import local
_thread_locals = local()
def set_current_user(user):
_thread_locals.user=user
def get_current_user():
return getattr(_thread_locals, 'user', None)
ウェブ以外の環境(管理コマンドなど)では
set_current_user
をスクリプトの先頭で呼び出す必要があります。
関連
-
[解決済み] Pythonでdatetime.timeにN秒を追加する標準的な方法は何ですか?
-
[解決済み] Pythonで配列を宣言して項目を追加する方法は?
-
[解決済み] Pythonで現在時刻を取得し、年、月、日、時、分に分割する方法は?
-
[解決済み] オブジェクトを作成し、それに属性を追加するにはどうすればよいですか?
-
[解決済み] FORループとIF文の組み合わせのPythonicな方法
-
[解決済み】datetime.dateとdatetime.timeのオブジェクトを組み合わせるPythonicな方法
-
[解決済み】ipython notebookでセルの実行時間を測定する簡単な方法
-
[解決済み] DataFrameの文字列、dtypeがobjectの場合
-
[解決済み] Flaskで非同期タスクを作る
-
[解決済み] Pythonの文字列書式をリストで使う
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Pythonです。未束縛のメソッドを束縛する?
-
[解決済み] バブルソートの宿題
-
[解決済み] Python 3でバイナリデータを標準出力に書き込むには?
-
[解決済み] PythonからSMTPを使用してメールを送信する
-
[解決済み] 古いバージョンのPythonにおける辞書のキーの並び順
-
[解決済み] djangoフレームワークでフォームフィールドから値を取得するには?
-
[解決済み] Pandasを使って、既存のExcelファイルに新しいシートを保存する方法は?
-
[解決済み] PythonのRequestsモジュールを使ってWebサイトに "ログイン "するには?
-
[解決済み] 新しいpip backtrackingの実行時問題の解決
-
[解決済み] データクラスとtyping.NamedTupleの主な使用例