django历史对象的价值观

时间:2013-02-01 08:59:26

标签: django

我知道那里有逆转,我知道django有完整的历史分支。但我非常希望坚持django对象的原始历史。我只需要确保我还保存OLD和NEW值。

默认情况下,django只保存发生的事情(例如更新)但不存储值。任何人都可以指向一些东西(片段或应用程序),它略微增强了django的默认历史记录,并且还存储了已编辑属性的值,而不仅仅是它被编辑的事实。

现在我的历史记录

  

9-01-2012 12:55:02 chnaged:time

我想要它说

  

9-01-2012 12:55:02 chnaged:时间从6到8

更新: ==>对于任何对我的解决方案感兴趣的人(基于下面的答案)..

  1. 将HistoryModel(object)类添加到我的models.py

       class HistoryModel(object):
             changed_fields = {}
    
  2. 在我的任何模型中继承

  3. 添加了pre_save接收器以保存旧值:

        @receiver(pre_save, sender=Customer) 
        def save_old_values(sender,**kwargs):
            #dont delete using in eval
            db_obj = sender.objects.get(pk=kwargs['instance'].pk)
            for field in kwargs['instance']._meta.fields:
                if not eval("db_obj." + str(field.get_attname_column()[0])) == eval("kwargs['instance']." +  str(field.get_attname_column()[0])):
                         kwargs['instance'].changed_fields[field.get_attname_column()[0]] = "from "+str(eval("db_obj." + str(field.get_attname_column()[0]))) + " to " + str(eval("kwargs['instance']." +  str(field.get_attname_column()[0])))
    
  4. 在我的管理员中覆盖了log_change方法并收集了object.changed_fields dict并将其存储为消息

2 个答案:

答案 0 :(得分:2)

这不是'默认django'。你正在使用一个贡献的django应用程序(the admin)所以它是一个像任何其他应用程序(即django-reversion)的应用程序,并且在这种程度上,它不支持开箱即用的功能。

幸运的是,django管理员非常可配置。您可以尝试ModelAdmin类的overwriting the log_change方法,并通过检测哪些字段已更改(通过将表单值与数据库值进行比较)使change_message更详细。据推测,您希望在项目中的所有应用程序中使用此功能,因此可以编写mixin来支持此功能,也可以分叉整个管理员并对功能进行硬编码。

答案 1 :(得分:1)

扩展有关更改的信息就足以覆盖ModelAdmin.construct_change_message方法。无需在模型上添加属性(例如,changed_fields),因为您可以从表单和表单集的初始数据构建日志消息。

这是一个记录每个更改字段的先前值的版本:

def construct_change_message(self, request, form, formsets):
    change_message = []
    if form.changed_data:
        msg_list = u''
        for field in form.changed_data:
            if form.initial[field] is not None and hasattr(form.fields[field], 'queryset'):
                old_value = form.fields[field].queryset.get(id=form.initial[field]).__unicode__()
            else:
                old_value = form.initial[field]
            msg_list = _("{0}field '{1}' from \"{2}\", ").format(msg_list, field, old_value)
        change_message.append(capfirst(_(u'changed {0}.').format(msg_list[:-2])))

    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_unicode(added_object._meta.verbose_name),
                                         'object': force_unicode(added_object)})
            for changed_object, changed_fields in formset.changed_objects :
                for form in formset.initial_forms:
                    if form.instance != changed_object:
                        continue
                    msg_list = u''
                    for field in changed_fields:
                        if form.initial[field] is not None and hasattr(form.fields[field], 'queryset'):
                            old_value = form.fields[field].queryset.get(id=form.initial[field]).__unicode__()
                        else:
                            old_value = form.initial[field]
                        msg_list = _("{0}field '{1}' from \"{2}\", ").format(msg_list, field, old_value)
                    change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                          % {'list': msg_list[:-2],
                                             'name': force_unicode(changed_object._meta.verbose_name),
                                             'object': force_unicode(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_unicode(deleted_object._meta.verbose_name),
                                         'object': force_unicode(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')