17
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DjangoAdvent Calendar 2017

Day 8

Djangoでモデルオブジェクトの変更前のデータをチェックする

Last updated at Posted at 2017-12-07

概要

  • 便利そうだから、いつか使いたいなと思いつつ、ニッチなのでなかなか使えない機能シリーズ
  • django-model-utils というライブラリがある
  • その中でも FieldTracker という機能が気に入っている。
  • 実際に仕事で使ったことはない

FieldTracker is 何?

簡単に言うと、saveする前のモデルオブジェクトに何かしら変更があったらそれを検知できる機能

from django.db import models
from model_utils import FieldTracker

class Post(models.Model):
    title = models.CharField(max_length=100)
    body = models.TextField()

    tracker = FieldTracker()

例えば、こういうモデルがあるとする

変更前の情報を取得する

変更が入ったフィールドの変更前のデータが取得できる

>>> a = Post.objects.create(title='First Post')
>>> a.title = 'Welcome'
>>> a.tracker.previous('title')
u'First Post'

変更したかどうかチェックする

そのフィールドに変更があったか判定できる

>>> a = Post.objects.create(title='First Post')
>>> a.title = 'Welcome'
>>> a.tracker.has_changed('title')
True
>>> a.tracker.has_changed('body')
False

変更前のデータを辞書で取得する

変更前のデータを辞書として丸っと受け取れる

>>> a = Post.objects.create(title='First Post')
>>> a.title = 'Welcome'
>>> a.body = 'First post!'
>>> a.tracker.changed()
{'title': 'First Post', 'body': ''}

特定のフィールドだけ対象にしたい

fieldsを指定すれば良い

title_tracker = FieldTracker(fields=['title'])
>>> a = Post.objects.create(title='First Post')
>>> a.body = 'First post!'
>>> a.title_tracker.changed()
{'title': None}

どうですか便利じゃないですか!? けどイマイチよし使おうってケースに遭遇しないんですよね...w

注意点

  • これはモデルのバージョン管理をしてくれるわけじゃない
  • 単純にモデルオブジェクトがsaveされるまでに変更があったら直前のデータを持ってくれてるというだけ。
  • saveすると直前のデータはリセットされる。

参考

17
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?