跟踪Django中的字段更改

时间:2015-05-09 09:38:47

标签: python django

我想跟踪模型字段中所做的更改。让我们说它是posts_status。选择是开放和关闭。因此,我想跟踪它何时从关闭打开并从打开时关闭。

为此,我尝试了django-simple-history,但在此我看不到最后的状态。表示它仅在更新日期时提供当前状态。所以我也需要显示以前的状态。我该怎么办?

我想问的另一件事:如果我删除一些字段并进行迁移那么效果会是什么?请帮帮我。我在最后几天坚持不懈。 :(

class Job_posting(models.Model):                                                            user = models.ForeignKey(User, on_delete=models.DO_NOTHING,      blank=True)                                             
    POSTING_CHOICES = (                     
        ('O', 'Open'),                    
        ('P', 'Pause'),                   
        ('C', 'Close'),
    )                  
    OFFER_LETTER_CHOICES = (              
        ('YES', 'Yes'),                   
        ('NO', 'No'),
    )

    posting_status = models.CharField(max_length=1, choices=POSTING_CHOICES)
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
    org = models.ForeignKey(Organization, null=True, blank=True, default=None)                                                       

    job_title = models.CharField(max_length=255, blank=True, null=True)
    history = HistoricalRecords()

我正在通过SQL命令进行检查。

2 个答案:

答案 0 :(得分:1)

django-simple-history可以解决您的问题。

POSTING_CHOICES = (                     
    ('O', 'Open'),                    
    ('P', 'Pause'),                   
    ('C', 'Close'),
)                  

class Job_posting(models.Model):
    posting_status = models.CharField(max_length=1, choices=POSTING_CHOICES)
    history = HistoricalRecords()

测试:

# jp1 = Job_posting.objects.create(posting_status='O')
# jp1.posting_status = 'P'
# jp1.save()
# jp1.history.last().posting_status
u'O'

请注意,history是每个模型而不是每个字段的状态。

答案 1 :(得分:0)

也许是非正统的解决方案,但也许可以在pre_save信号上复制模型,然后在post_save信号上检查是否有任何克隆,检查差异,然后为任何更改创建历史项。 E.g。

class BlogPost(models.Model):
    posting_status = models.CharField(max_length=30)
    # Using a CharField because your question doesn't make a lot of sense for a BooleanField, if it's changed and it's True then it was surely False before.

class Clone(BlogPost):
    blogpost_id = models.PositiveIntegerField()

# You'll also need a place to store the histories:

class HistoryItem(models.Model):
    blogpost = models.ForeignKey(BlogPost, related_name='posting_status_history')
    timestamp = models.DateTimeField(auto_now_add=True)
    old_value = models.CharField(max_length=30)
    new_value = models.CharField(max_length=30)

# Then simple dirty checking of the field before and after it's saved

@receiver(pre_save, sender=BlogPost)
def create_clone(sender, **kwargs):
    instance = kwargs.pop('instance', None)
    created = kwargs.pop('created', False)
    if not created and instance is not None:
        old_instance = BlogPost.objects.get(id=instance.id)  # This is pre-save so the object in db will have old values
        Clone.objects.create(blogpost_id=instance.id, posting_status=old_instance.posting_status, commit=True)

@receiver(post_save, sender=BlogPost)
def check_changes(sender, **kwargs):
    instance = kwargs.pop('instance', None)
    created = kwargs.pop('created', False)
    if not created and instance is not None:
        old_instance = Clone.objects.filter(blogpost_id=instance.id)
        old_value = old_instance.posting_status
        new_value = instance.posting_status
        if old_value != new_value:
            HistoryItem.objects.create(blogpost=instance, old_value=old_value, new_value=new_value)
        old_instance.delete()  # Clear up the clone

之后,包含更改的BlogPost项目将包含posting_status_history相关对象管理器,您可以使用blogpost.posting_status_history.all()

进行查询