mirror of
https://github.com/jazzband/django-auditlog.git
synced 2026-03-16 22:20:26 +00:00
Add flake8 to pre-commit config (#387)
This commit is contained in:
parent
be973ca71f
commit
11dceb81b8
9 changed files with 68 additions and 48 deletions
|
|
@ -8,6 +8,11 @@ repos:
|
|||
args:
|
||||
- "--target-version"
|
||||
- "py37"
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: "4.0.1"
|
||||
hooks:
|
||||
- id: flake8
|
||||
args: ["--max-line-length", "110"]
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.10.1
|
||||
hooks:
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ def track_field(field):
|
|||
|
||||
def get_fields_in_model(instance):
|
||||
"""
|
||||
Returns the list of fields in the given model instance. Checks whether to use the official _meta API or use the raw
|
||||
data. This method excludes many to many fields.
|
||||
Returns the list of fields in the given model instance. Checks whether to use the official
|
||||
_meta API or use the raw data. This method excludes many to many fields.
|
||||
|
||||
:param instance: The model instance to get the fields for
|
||||
:type instance: Model
|
||||
|
|
@ -90,8 +90,9 @@ def mask_str(value: str) -> str:
|
|||
|
||||
def model_instance_diff(old, new, fields_to_check=None):
|
||||
"""
|
||||
Calculates the differences between two model instances. One of the instances may be ``None`` (i.e., a newly
|
||||
created model or deleted model). This will cause all fields with a value to have changed (from ``None``).
|
||||
Calculates the differences between two model instances. One of the instances may be ``None``
|
||||
(i.e., a newly created model or deleted model). This will cause all fields with a value to have
|
||||
changed (from ``None``).
|
||||
|
||||
:param old: The old state of the model instance.
|
||||
:type old: Model
|
||||
|
|
@ -100,8 +101,8 @@ def model_instance_diff(old, new, fields_to_check=None):
|
|||
:param fields_to_check: An iterable of the field names to restrict the diff to, while ignoring the rest of
|
||||
the model's fields. This is used to pass the `update_fields` kwarg from the model's `save` method.
|
||||
:type fields_to_check: Iterable
|
||||
:return: A dictionary with the names of the changed fields as keys and a two tuple of the old and new field values
|
||||
as value.
|
||||
:return: A dictionary with the names of the changed fields as keys and a two tuple of the old and new
|
||||
field values as value.
|
||||
:rtype: dict
|
||||
"""
|
||||
from auditlog.registry import auditlog
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ from auditlog.context import set_actor
|
|||
|
||||
class AuditlogMiddleware:
|
||||
"""
|
||||
Middleware to couple the request's user to log items. This is accomplished by currying the signal receiver with the
|
||||
user from the request (or None if the user is not authenticated).
|
||||
Middleware to couple the request's user to log items. This is accomplished by currying the
|
||||
signal receiver with the user from the request (or None if the user is not authenticated).
|
||||
"""
|
||||
|
||||
def __init__(self, get_response=None):
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ class LogEntryManager(models.Manager):
|
|||
|
||||
def log_create(self, instance, **kwargs):
|
||||
"""
|
||||
Helper method to create a new log entry. This method automatically populates some fields when no explicit value
|
||||
is given.
|
||||
Helper method to create a new log entry. This method automatically populates some fields when no
|
||||
explicit value is given.
|
||||
|
||||
:param instance: The model instance to log a change for.
|
||||
:type instance: Model
|
||||
|
|
@ -47,8 +47,8 @@ class LogEntryManager(models.Manager):
|
|||
if callable(get_additional_data):
|
||||
kwargs.setdefault("additional_data", get_additional_data())
|
||||
|
||||
# Delete log entries with the same pk as a newly created model. This should only be necessary when an pk is
|
||||
# used twice.
|
||||
# Delete log entries with the same pk as a newly created model.
|
||||
# This should only be necessary when an pk is used twice.
|
||||
if kwargs.get("action", None) is LogEntry.Action.CREATE:
|
||||
if (
|
||||
kwargs.get("object_id", None) is not None
|
||||
|
|
@ -211,21 +211,21 @@ class LogEntryManager(models.Manager):
|
|||
|
||||
class LogEntry(models.Model):
|
||||
"""
|
||||
Represents an entry in the audit log. The content type is saved along with the textual and numeric (if available)
|
||||
primary key, as well as the textual representation of the object when it was saved. It holds the action performed
|
||||
and the fields that were changed in the transaction.
|
||||
Represents an entry in the audit log. The content type is saved along with the textual and numeric
|
||||
(if available) primary key, as well as the textual representation of the object when it was saved.
|
||||
It holds the action performed and the fields that were changed in the transaction.
|
||||
|
||||
If AuditlogMiddleware is used, the actor will be set automatically. Keep in mind that editing / re-saving LogEntry
|
||||
instances may set the actor to a wrong value - editing LogEntry instances is not recommended (and it should not be
|
||||
necessary).
|
||||
If AuditlogMiddleware is used, the actor will be set automatically. Keep in mind that
|
||||
editing / re-saving LogEntry instances may set the actor to a wrong value - editing LogEntry
|
||||
instances is not recommended (and it should not be necessary).
|
||||
"""
|
||||
|
||||
class Action:
|
||||
"""
|
||||
The actions that Auditlog distinguishes: creating, updating and deleting objects. Viewing objects is not logged.
|
||||
The values of the actions are numeric, a higher integer value means a more intrusive action. This may be useful
|
||||
in some cases when comparing actions because the ``__lt``, ``__lte``, ``__gt``, ``__gte`` lookup filters can be
|
||||
used in queries.
|
||||
The actions that Auditlog distinguishes: creating, updating and deleting objects. Viewing objects
|
||||
is not logged. The values of the actions are numeric, a higher integer value means a more intrusive
|
||||
action. This may be useful in some cases when comparing actions because the ``__lt``, ``__lte``,
|
||||
``__gt``, ``__gte`` lookup filters can be used in queries.
|
||||
|
||||
The valid actions are :py:attr:`Action.CREATE`, :py:attr:`Action.UPDATE` and :py:attr:`Action.DELETE`.
|
||||
"""
|
||||
|
|
@ -308,9 +308,9 @@ class LogEntry(models.Model):
|
|||
@property
|
||||
def changes_str(self, colon=": ", arrow=" \u2192 ", separator="; "):
|
||||
"""
|
||||
Return the changes recorded in this log entry as a string. The formatting of the string can be customized by
|
||||
setting alternate values for colon, arrow and separator. If the formatting is still not satisfying, please use
|
||||
:py:func:`LogEntry.changes_dict` and format the string yourself.
|
||||
Return the changes recorded in this log entry as a string. The formatting of the string can be
|
||||
customized by setting alternate values for colon, arrow and separator. If the formatting is still
|
||||
not satisfying, please use :py:func:`LogEntry.changes_dict` and format the string yourself.
|
||||
|
||||
:param colon: The string to place between the field name and the values.
|
||||
:param arrow: The string to place between each old and new value.
|
||||
|
|
@ -377,7 +377,7 @@ class LogEntry(models.Model):
|
|||
values_display.append(choices_dict.get(value, "None"))
|
||||
except ValueError:
|
||||
values_display.append(choices_dict.get(value, "None"))
|
||||
except:
|
||||
except Exception:
|
||||
values_display.append(choices_dict.get(value, "None"))
|
||||
else:
|
||||
try:
|
||||
|
|
@ -414,21 +414,22 @@ class LogEntry(models.Model):
|
|||
|
||||
class AuditlogHistoryField(GenericRelation):
|
||||
"""
|
||||
A subclass of py:class:`django.contrib.contenttypes.fields.GenericRelation` that sets some default variables. This
|
||||
makes it easier to access Auditlog's log entries, for example in templates.
|
||||
A subclass of py:class:`django.contrib.contenttypes.fields.GenericRelation` that sets some default
|
||||
variables. This makes it easier to access Auditlog's log entries, for example in templates.
|
||||
|
||||
By default this field will assume that your primary keys are numeric, simply because this is the most common case.
|
||||
However, if you have a non-integer primary key, you can simply pass ``pk_indexable=False`` to the constructor, and
|
||||
Auditlog will fall back to using a non-indexed text based field for this model.
|
||||
By default this field will assume that your primary keys are numeric, simply because this is the most
|
||||
common case. However, if you have a non-integer primary key, you can simply pass ``pk_indexable=False``
|
||||
to the constructor, and Auditlog will fall back to using a non-indexed text based field for this model.
|
||||
|
||||
Using this field will not automatically register the model for automatic logging. This is done so you can be more
|
||||
flexible with how you use this field.
|
||||
Using this field will not automatically register the model for automatic logging. This is done so you
|
||||
can be more flexible with how you use this field.
|
||||
|
||||
:param pk_indexable: Whether the primary key for this model is not an :py:class:`int` or :py:class:`long`.
|
||||
:type pk_indexable: bool
|
||||
:param delete_related: By default, including a generic relation into a model will cause all related objects to be
|
||||
cascade-deleted when the parent object is deleted. Passing False to this overrides this behavior, retaining
|
||||
the full auditlog history for the object. Defaults to True, because that's Django's default behavior.
|
||||
:param delete_related: By default, including a generic relation into a model will cause all related
|
||||
objects to be cascade-deleted when the parent object is deleted. Passing False to this overrides this
|
||||
behavior, retaining the full auditlog history for the object. Defaults to True, because that's
|
||||
Django's default behavior.
|
||||
:type delete_related: bool
|
||||
"""
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ def log_create(sender, instance, created, **kwargs):
|
|||
if created:
|
||||
changes = model_instance_diff(None, instance)
|
||||
|
||||
log_entry = LogEntry.objects.log_create(
|
||||
LogEntry.objects.log_create(
|
||||
instance,
|
||||
action=LogEntry.Action.CREATE,
|
||||
changes=json.dumps(changes),
|
||||
|
|
@ -38,7 +38,7 @@ def log_update(sender, instance, **kwargs):
|
|||
|
||||
# Log an entry only if there are changes
|
||||
if changes:
|
||||
log_entry = LogEntry.objects.log_create(
|
||||
LogEntry.objects.log_create(
|
||||
instance,
|
||||
action=LogEntry.Action.UPDATE,
|
||||
changes=json.dumps(changes),
|
||||
|
|
@ -54,7 +54,7 @@ def log_delete(sender, instance, **kwargs):
|
|||
if instance.pk is not None:
|
||||
changes = model_instance_diff(instance, None)
|
||||
|
||||
log_entry = LogEntry.objects.log_create(
|
||||
LogEntry.objects.log_create(
|
||||
instance,
|
||||
action=LogEntry.Action.DELETE,
|
||||
changes=json.dumps(changes),
|
||||
|
|
|
|||
|
|
@ -270,7 +270,8 @@ class AuditlogModelRegistry:
|
|||
)
|
||||
if "." not in item["model"]:
|
||||
raise ValueError(
|
||||
"Setting 'AUDITLOG_INCLUDE_TRACKING_MODELS' model must be in the format <app_name>.<model_name>"
|
||||
"Setting 'AUDITLOG_INCLUDE_TRACKING_MODELS' model must be in the "
|
||||
"format <app_name>.<model_name>"
|
||||
)
|
||||
|
||||
if settings.AUDITLOG_INCLUDE_ALL_MODELS:
|
||||
|
|
|
|||
|
|
@ -73,7 +73,10 @@ class AuditlogFlushTest(TestCase):
|
|||
out, err = self.call_command("--before-date=2000-01-01")
|
||||
self.assertEqual(
|
||||
out,
|
||||
"This action will clear all log entries before 2000-01-01 from the database.\nAborted.",
|
||||
(
|
||||
"This action will clear all log entries before "
|
||||
"2000-01-01 from the database.\nAborted."
|
||||
),
|
||||
msg="Output shows warning with date and then aborted.",
|
||||
)
|
||||
self.assertEqual(err, "", msg="No stderr")
|
||||
|
|
|
|||
|
|
@ -108,13 +108,17 @@ class SimpleModelTest(TestCase):
|
|||
self.assertJSONEqual(
|
||||
obj.history.get(action=LogEntry.Action.UPDATE).changes,
|
||||
'{"boolean": ["False", "True"]}',
|
||||
msg="Object modifications that are not saved to DB are not logged when using the `update_fields`.",
|
||||
msg=(
|
||||
"Object modifications that are not saved to DB are not logged "
|
||||
"when using the `update_fields`."
|
||||
),
|
||||
)
|
||||
|
||||
def test_django_update_fields_edge_cases(self):
|
||||
"""
|
||||
The test ensures that if Django's `update_fields` behavior ever changes for special values `(None, [])`, the
|
||||
package should too. https://docs.djangoproject.com/en/3.2/ref/models/instances/#specifying-which-fields-to-save
|
||||
The test ensures that if Django's `update_fields` behavior ever changes for special
|
||||
values `(None, [])`, the package should too.
|
||||
https://docs.djangoproject.com/en/3.2/ref/models/instances/#specifying-which-fields-to-save
|
||||
"""
|
||||
obj = self.obj
|
||||
|
||||
|
|
@ -1050,7 +1054,10 @@ class RegisterModelSettingsTest(TestCase):
|
|||
with override_settings(AUDITLOG_INCLUDE_TRACKING_MODELS=({"model": "test"},)):
|
||||
with self.assertRaisesMessage(
|
||||
ValueError,
|
||||
"Setting 'AUDITLOG_INCLUDE_TRACKING_MODELS' model must be in the format <app_name>.<model_name>",
|
||||
(
|
||||
"Setting 'AUDITLOG_INCLUDE_TRACKING_MODELS' model must be in the "
|
||||
"format <app_name>.<model_name>"
|
||||
),
|
||||
):
|
||||
self.test_auditlog.register_from_settings()
|
||||
|
||||
|
|
@ -1286,7 +1293,8 @@ class DiffMsgTest(TestCase):
|
|||
(
|
||||
"<table>"
|
||||
"<tr><th>#</th><th>Field</th><th>From</th><th>To</th></tr>"
|
||||
"<tr><td>1</td><td>field one</td><td>old value of field one</td><td>new value of field one</td></tr>"
|
||||
"<tr><td>1</td><td>field one</td><td>old value of field one</td>"
|
||||
"<td>new value of field one</td></tr>"
|
||||
"<tr><td>2</td><td>field two</td><td>11</td><td>42</td></tr>"
|
||||
"</table>"
|
||||
),
|
||||
|
|
@ -1309,7 +1317,8 @@ class DiffMsgTest(TestCase):
|
|||
(
|
||||
"<table>"
|
||||
"<tr><th>#</th><th>Relationship</th><th>Action</th><th>Objects</th></tr>"
|
||||
"<tr><td>1</td><td>some_m2m_field</td><td>add</td><td>Example User (user 1)<br>Illustration (user 42)</td></tr>"
|
||||
"<tr><td>1</td><td>some_m2m_field</td><td>add</td><td>Example User (user 1)"
|
||||
"<br>Illustration (user 42)</td></tr>"
|
||||
"</table>"
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ sys.path.insert(0, os.path.abspath("../../"))
|
|||
|
||||
# Setup Django for autodoc
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "auditlog_tests.test_settings")
|
||||
import django
|
||||
import django # noqa: E402
|
||||
|
||||
django.setup()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue