跳转到主要内容

用于跟踪模型字段更改的Django应用程序。

项目描述

https://badge.fury.io/py/django-field-history.svg Documentation Status https://travis-ci.org/grantmcconnaughey/django-field-history.svg?branch=master https://coveralls.io/repos/github/grantmcconnaughey/django-field-history/badge.svg?branch=master

用于跟踪模型字段更改的Django应用程序。适用于Python 2.7/3.4+和Django 1.11/2.0+。

其他类似的应用程序包括 django-reversiondjango-simple-history,它们跟踪 所有 模型字段。

项目

django-field-history

django-reversion

django-simple-history

管理集成

不适用

所有/某些字段

某些

某些

所有

对象历史

模型历史

不适用

多对象版本

不适用

额外的模型管理器

模型注册

Django视图助手

管理器辅助方法

不适用

是 (as_of, most_recent)

MySQL支持

额外配置

完整

完整

文档

完整文档位于 https://django-field-history.readthedocs.io

功能

  • 保留特定模型字段所有更改的历史记录。

  • 存储字段的名称、值、更改日期和时间以及更改用户。

  • 与所有模型字段类型(除ManyToManyField外)兼容。

快速入门

安装 django-field-history

pip install django-field-history

确保将其放在 INSTALLED_APPS 中。

INSTALLED_APPS = [
    # other apps...
    'field_history',
]

然后将它添加到您的模型中。

from field_history.tracker import FieldHistoryTracker

class PizzaOrder(models.Model):
    STATUS_CHOICES = (
        ('ORDERED', 'Ordered'),
        ('COOKING', 'Cooking'),
        ('COMPLETE', 'Complete'),
    )
    status = models.CharField(max_length=64, choices=STATUS_CHOICES)

    field_history = FieldHistoryTracker(['status'])

现在每次您更改订单的状态字段时,该更改的信息都将存储在数据库中。

from field_history.models import FieldHistory

# No FieldHistory objects yet
assert FieldHistory.objects.count() == 0

# Creating an object will make one
pizza_order = PizzaOrder.objects.create(status='ORDERED')
assert FieldHistory.objects.count() == 1

# This object has some fields on it
history = FieldHistory.objects.get()
assert history.object == pizza_order
assert history.field_name == 'status'
assert history.field_value == 'ORDERED'
assert history.date_created is not None

# You can query FieldHistory using the get_{field_name}_history()
# method added to your model
histories = pizza_order.get_status_history()
assert list(FieldHistory.objects.all()) == list(histories)

# Or using the custom FieldHistory manager
histories2 = FieldHistory.objects.get_for_model_and_field(pizza_order, 'status')
assert list(histories) == list(histories2)

# Updating that particular field creates a new FieldHistory
pizza_order.status = 'COOKING'
pizza_order.save()
assert FieldHistory.objects.count() == 2

updated_history = histories.latest()
assert updated_history.object == pizza_order
assert updated_history.field_name == 'status'
assert updated_history.field_value == 'COOKING'
assert updated_history.date_created is not None

管理命令

django-field-history附带一些管理命令。

createinitialfieldhistory

此命令将检查您应用中的所有模型,并为具有FieldHistoryTracker的模型创建FieldHistory对象。在您首次安装django-field-history时运行此命令。

python manage.py createinitialfieldhistory

renamefieldhistory

在更改您使用FieldHistoryTracker跟踪的字段名称后,请使用此命令。

python manage.py renamefieldhistory --model=app_label.model_name --from_field=old_field_name --to_field=new_field_name

例如,如果您有此模型

class Person(models.Model):
    username = models.CharField(max_length=255)

    field_history = FieldHistoryTracker(['username'])

并且您将username字段名称更改为handle

class Person(models.Model):
    handle = models.CharField(max_length=255)

    field_history = FieldHistoryTracker(['handle'])

您还需要更新指向此模型的全部FieldHistory对象中的field_name

python manage.py renamefieldhistory --model=myapp.Person --from_field=username --to_field=handle

存储更改字段的用户

有两种方法可以存储更改模型字段的用户。最简单的方法是使用发起请求的已登录用户。为此,将FieldHistoryMiddleware类添加到您的MIDDLEWARE设置中。

MIDDLEWARE = [
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'field_history.middleware.FieldHistoryMiddleware',
]

或者,您可以在具有您跟踪的字段的模型中添加一个_field_history_user属性。此属性应在您的字段更新时返回要存储在FieldHistory中的用户。

class Pizza(models.Model):
    name = models.CharField(max_length=255)
    updated_by = models.ForeignKey('auth.User')

    field_history = FieldHistoryTracker(['name'])

    @property
    def _field_history_user(self):
        return self.updated_by

与MySQL协作

如果您使用MySQL,则在运行迁移时默认配置将抛出异常。(默认情况下,FieldHistory.object_id实现为TextField以提供灵活性,但MySQL InnoDB表中的索引列最大为767字节。)要修复此问题,您可以在settings.py中将FIELD_HISTORY_OBJECT_ID_TYPE设置为覆盖默认字段类型,以使用满足MySQL约束的类型。 FIELD_HISTORY_OBJECT_ID_TYPE可以设置为以下之一

  1. 您希望使用的Django模型字段类,或者

  2. 一个元组 (field_class, kwargs),其中field_class是Django模型字段类,kwargs是要传递给字段类构造函数的参数字典。

为了在MySQL中使用与Postgres相似的默认行为配置object_id以使用CharField,请将以下内容添加到settings.py中

from django.db import models
FIELD_HISTORY_OBJECT_ID_TYPE = (models.CharField, {'max_length': 100})

FIELD_HISTORY_OBJECT_ID_TYPE还允许您使用更适用于您用例的字段类型,即使您使用Postgres(或类似的无约束数据库)。例如,如果您始终允许Django自动创建一个id字段(内部实现为AutoField),将FIELD_HISTORY_OBJECT_ID_TYPE设置为IntegerField将导致效率提升(时间和空间)。这看起来像

from django.db import models
FIELD_HISTORY_OBJECT_ID_TYPE = models.IntegerField

运行测试

代码实际上工作吗?

source <YOURVIRTUALENV>/bin/activate
(myenv) $ pip install -r requirements-test.txt
(myenv) $ python runtests.py

历史

0.8.0(2020年1月5日)

  • 增加了对Django 2.2和3.0的支持

  • 增加了对Python 3.8的支持

0.7.0(2018年9月3日)

  • 增加了对Django 2.0和2.1的支持

  • 增加了对Python 3.7的支持

  • 删除了对Django 1.7到1.10的支持

  • 删除了对Python 3.2和3.3的支持

  • 修复了带有createinitialfieldhistory命令的泛型主键错误(#20)

0.6.0(2016年12月22日)

  • 增加了对Django 1.10的兼容性。

  • 增加了对MySQL的兼容性。

  • 修复了会重复跟踪字段的问题。

0.5.0(2016年4月16日)

  • 增加了跟踪父模型字段历史的能力。

  • 增加了对Django 1.7的兼容性。

0.4.0(2016年2月24日)

  • 增加了一种方法,可以在FieldHistory.user上自动存储已登录用户。

0.3.0 (2016年2月20日)

  • FieldHistory 对象现在使用 bulk_create 创建,这意味着即使在同时更改多个字段时,也只会执行一个查询。

  • 增加了一种存储哪个用户更新了字段的方法。

  • get_latest_by 添加到 FieldHistory Meta 选项中,以便可以使用 .latest().earliest()

  • 添加了 createinitialfieldhistory 管理命令。

  • 添加了 renamefieldhistory 管理命令。

0.2.0 (2016年2月17日)

  • 首次在 PyPI 上发布。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源分布

django-field-history-0.8.0.tar.gz (13.1 kB 查看哈希值)

上传时间

构建分布

django_field_history-0.8.0-py2.py3-none-any.whl (14.5 kB 查看哈希值)

上传时间 Python 2 Python 3

由以下机构支持