Code Monkey home page Code Monkey logo

django-audit-log's People

Contributors

ansmirnov avatar decibyte avatar ghinch avatar gitter-badger avatar janmalte avatar kweku avatar movermeyer avatar vvangelovski avatar wkang0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-audit-log's Issues

action_user / action_user_id always blank

Running into an issue, I can confirm that user is logged in (me) and when edit is made and logged without error. However, the action_user /action_user_id is always blank. This should only occur if user is annonymouss, correct?

Where should I start looking? I've reviewed the code and it appears as the fields.py is the interesting bit, but not sure where to start.

Best,

Jeff

Django 1.10

well, you need to update the middleware.py
import this
from django.utils.deprecation import MiddlewareMixin
and add here:
class UserLoggingMiddleware(MiddlewareMixin): line 24-25

Auditing User model changes

Hi

I am using this module in a project and I have a class inheriting from AbstractBaseUser and then in the settings I point AUTH_USER_MODEL to this new class. However if I try to put AuditLog on this table I get an issue whenever there is an update on this table. I have debugged the code for AuditLog and found the problem in the following lines:

        #check if the manager has been attached to auth user model
        if [model._meta.app_label, model.__name__] == getattr(settings, 'AUTH_USER_MODEL', 'auth.User').split("."):
            action_user_field = LastUserField(related_name = rel_name, editable = False, to = 'self')

Removing this then it start complaining that my class is not yet installed or is abstract. Anyone had this issue? Is this a problem with AuditLog or there is another way how to do it?

Incompatilbility with `django-modeltranslation` during tests

I have a Django project using both django-audit-log and django-modeltranslation.

I've been using the audit log for a while without any issues. Now that I introduced translations, a lot of my tests are blowing up. I'm sure the same would have happened if had introduced audit log after translations, so I'm not blaming any of the projects. I just wish they would both work together. But I'm unfortunately not able to find out what the problem is myself.

A weird thing is that this seems to only be a problem during testing. Everything seems to work as expected when running the project normally. But I want my tests to work as well.

I've created another small example Django project to provide a case for this issue.

The complete output from running tests is here:

$ ./manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E
======================================================================
ERROR: test_my_model (app.tests.MyModelTestCase)
Test the model.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/path/to/django-auditlog-modeltranslation-testcase/app/tests.py", line 12, in setUp
    text='Text of Instance 1'
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/modeltranslation/manager.py", line 381, in create
    return super(MultilingualQuerySet, self).create(**kwargs)
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/django/db/models/query.py", line 394, in create
    obj.save(force_insert=True, using=self.db)
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/django/db/models/base.py", line 807, in save
    force_update=force_update, update_fields=update_fields)
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/django/db/models/base.py", line 847, in save_base
    update_fields=update_fields, raw=raw, using=using,
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/django/dispatch/dispatcher.py", line 193, in send
    for receiver in self._live_receivers(sender)
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/django/dispatch/dispatcher.py", line 193, in <listcomp>
    for receiver in self._live_receivers(sender)
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/audit_log/models/managers.py", line 107, in post_save
    self.create_log_entry(instance, created and 'I' or 'U')
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/audit_log/models/managers.py", line 102, in create_log_entry
    manager.create(action_type = action_type, **attrs)
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/django/db/models/query.py", line 392, in create
    obj = self.model(**kwargs)
  File "/path/to/django-auditlog-modeltranslation-testcase/.env/lib/python3.5/site-packages/django/db/models/base.py", line 572, in __init__
    raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
TypeError: 'text_es' is an invalid keyword argument for this function

----------------------------------------------------------------------
Ran 1 test in 0.003s

FAILED (errors=1)
Destroying test database for alias 'default'...

I've also reported the issue for django-modeltranslation.

Saves User as None when when type(self.request.user) is not SimpleLazyObject

I am using:
djangorestframework==3.2.4
djangorestframework-jwt==1.7.2
Django==1.8.2
django-audit-log==0.7.0

Basically when I make post request for saving an object using session Authentication it sets created_by user fine.

But when I use JWT, user is not encapsulated inside SimpleLazyObject and then Audit-Log saves None.

If you can give me a clue or a workaround will be great.

Output:
self.assertEqual(post.created_by.username, "user01")
AttributeError: 'NoneType' object has no attribute 'username'

My Test:
class PostsWithJWTTestCase(APITestCase):

def test_user_can_write_posts_to_a_course(self):
    UserFactory.create(username='pdamicol', password='paolo')

    course = CourseFactory.create(subject=None,
                                  image=None,
                                  professor=None,
                                  student_group=None)

    response = self.client.post('/api-token-auth/',
                                {
                                    "username": "user01",
                                    "password": "pass"
                                },
                                format='json')

    token = response.data['token']

    self.client.credentials(HTTP_AUTHORIZATION='JWT '+token)

    self.assertEqual(response.status_code, status.HTTP_200_OK)

    self.client.post('/courses/'+str(course.id)+'/posts/',
                     {'text': "This is post 1"},
                     format='json')

    post = Post.objects.first()

    self.assertEqual(post.text, "This is post 1")

    self.assertEqual(post.created_by.username, "user01")

    self.client.logout()

Creating a queryset for active data

I want to have access to the action_date, action_user attributes within a queryset. Goal is use this queryset for django-tables2 and django-import-export.

For django_table2 I can take an accessor like described here:

 accessor='audit_log.action_user'

But this way ordering fails as audit_log is no valid field.

Django import_export does not have accessor attribute at all.

My idea to workaround that is to build a queryset with a filter that excludes all but the active entries. How may achieve that?

Something like that comes to mind but I don't know what attribute of the audit_log model is related to the active model?

 models.PlannedMachine.audit_log.filter(id__in=PlannedMachine.objects.all())

auditlog error in django 1.11

Hi,

I installed django 1.11 and followed the doc to add 'audit-log' MIDDLEWARE, the migrate was doing success, however, when I start run_server, the below error shows:
Unhandled exception in thread started by <function check_errors..wrapper at 0x7f9567d38510>
Traceback (most recent call last):
File "/home/oscar/venvs/acnts_env/lib/python3.5/site-packages/django/utils/autoreload.py", line 227, in wrapper
fn(*args, **kwargs)
File "/home/oscar/venvs/acnts_env/lib/python3.5/site-packages/django/core/management/commands/runserver.py", line 147, in inner_run
handler = self.get_handler(*args, **options)
File "/home/oscar/venvs/acnts_env/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/runserver.py", line 27, in get_handler
handler = super(Command, self).get_handler(*args, **options)
File "/home/oscar/venvs/acnts_env/lib/python3.5/site-packages/django/core/management/commands/runserver.py", line 68, in get_handler
return get_internal_wsgi_application()
File "/home/oscar/venvs/acnts_env/lib/python3.5/site-packages/django/core/servers/basehttp.py", line 47, in get_internal_wsgi_application
return import_string(app_path)
File "/home/oscar/venvs/acnts_env/lib/python3.5/site-packages/django/utils/module_loading.py", line 20, in import_string
module = import_module(module_path)
File "/home/oscar/venvs/acnts_env/lib/python3.5/importlib/init.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 986, in _gcd_import
File "", line 969, in _find_and_load
File "", line 958, in _find_and_load_unlocked
File "", line 673, in _load_unlocked
File "", line 665, in exec_module
File "", line 222, in _call_with_frames_removed
File "/srv/apps/oo/accounts/accounts/wsgi.py", line 16, in
application = get_wsgi_application()
File "/home/oscar/venvs/acnts_env/lib/python3.5/site-packages/django/core/wsgi.py", line 14, in get_wsgi_application
return WSGIHandler()
File "/home/oscar/venvs/acnts_env/lib/python3.5/site-packages/django/core/handlers/wsgi.py", line 151, in init
self.load_middleware()
File "/home/oscar/venvs/acnts_env/lib/python3.5/site-packages/django/core/handlers/base.py", line 82, in load_middleware
mw_instance = middleware(handler)
TypeError: object() takes no parameters

Though when I comment out the line:
#'audit_log.middleware.UserLoggingMiddleware',

The app would run without errors

Django-rest framework 'module' object is not callable

I have a model like this
class ProductCategory(models.Model):
name = models.CharField(max_length=150, primary_key = True)
description = models.TextField()

audit_log = AuditLog()

my serializer:

class ProductCategorySerializer(serializers.ModelSerializer):
class Meta:
model = ProductCategory

I got this error
TypeError at /api/productcategoty/
'module' object is not callable

Do you know how to implement AuditLog() to work with rest framework?
Thank you
An

instance.delete() gives IntegrityError

I have the following model:

class Profile(BaseModel):
    audit_log = AuditLog()
    user = OneToOneField(AUTH_USER_MODEL, related_name='profile')
    phone = CharField(max_length=20)
    name = CharField(max_length=255)

and calling profile_instance.delete() give the following error:

IntegrityError: (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`test_db`.`profile_profileauditlogentry`, CONSTRAINT `user_id_refs_id_6c82164d` FOREIGN KEY (`user_id`) REFERENCES `custom_user_emailuser` (`id`))')

Is this a bug or am I misusing auditlog? For instance I note that the auditlog expects to store data about when a host instance is deleted, however I don't understand how the instance could ever hope to survive when it is enforcing relationships with the host instance?

Timezone Awareness for CreationDateTimeField

When saving a model with a CreationDateTimeField, I am getting the error that the field value is not timezone aware. (I have enabled timezone aware exceptions to happen in my Django development server.)

It is actually due to an issue in the Django code. From what I was reading, there have been debates to deprecate the auto_now and auto_now_add keyword arguments on DateTimeFields, but it hasn't happened yet and there haven't been any updates to that portion of their code base. I'm looking at it right now and wish I could just so easily change it for them.

The django-audit-log CreationDateTimeField and ModificationDateTimeField take advantage of these two keyword arguments. The general workaround seems to be to change the default value to timezone.now instead of utilizing those keyword arguments.

is not JSON serializable

I'm still using , Django 1.8 and python 2.7 ...

when i try to save my model , i receive the error...
<django.utils.functional.proxy object at 0x7f5ffe8cd590> is not JSON serializable

my method:
if not CustomStatusStep.objects.filter(company=obj, title=(u'Aberta')):
CustomStatusStep.objects.create(
company=obj,
title=
(u'Aberta'),
creator=request.user,
standard=True ...
)

and the error, i believes is in this part:
if created:
changes = model_instance_diff(None, instance)
log_entry = LogEntry.objects.log_create(
instance,
action=LogEntry.Action.CREATE,
changes=json.dumps(changes), ...
)

i believes , the error ocorre when i pass this parameter
title=_(u'Aberta') ....

there is some hack for this ?
so, how i can use ugettext_lazy whith django-udity-log ?

How can `modified_by` be manually set/updated?

In my application I have a model, let's call it ModelA, which does not use the AuthStampedModel mixin. I have another model, ModelB which uses the AuthStampedModel mixin.

Part of the functionality of my application includes handling a POST request that makes an update to a ModelA record, and then also makes an update to an associated ModelB record (based on application-specific business logic). When I make the update to the ModelB record I want its modified_by value to be set to the user who triggered the update to the ModelA record which then led to also updating the ModelB record.

However I'm stuck on how I would accomplish this. I've tried doing the following:

user = model_a_record.user
model_b_record.modified_by = user
model_b_record.save()

However this attempt to manually update modified_by does not work. I assumed this would be because modified_by is a LastUserField which has a default of editable=False, but even after creating my own EditableAuthStampedModel where the modified_by field is set to a LastUserField with an explicit value of editable=True, the modified_by value that I manually set does not get saved.

Any ideas?

Middleware raises ObjectDoesNotExist error when used in child models of django-polymorphic

The problem is that the _disable_audit_log_managers and _enable_audit_log_managers module functions in middleware.py only catch AttributeError when looking for an AuditLog instance. When the instance is a child model of a django-polymorphic, an ObjectDoesNotExist error is encountered first. The fix is safe and simple. Add ObjectDoesNotExist as an exception to also ignore.

[2018-03-14 11:09:33,471] ERROR django.request Internal Server Error: /exhibit_activity/new
Traceback (most recent call last):
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/nlm/occs/decorators.py", line 32, in wrapper
    return view_func(request, *args, **kwargs)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/contrib/auth/mixins.py", line 56, in dispatch
    return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/views/generic/base.py", line 88, in dispatch
    return handler(request, *args, **kwargs)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/views/generic/edit.py", line 217, in post
    return super(BaseCreateView, self).post(request, *args, **kwargs)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/views/generic/edit.py", line 183, in post
    return self.form_valid(form)
  File "/Users/massere/Projects/outreach-django/outreach/views.py", line 413, in form_valid
    return super(ActivityFormMixin, self).form_valid(form)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/views/generic/edit.py", line 162, in form_valid
    self.object = form.save()
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/forms/models.py", line 468, in save
    self.instance.save()
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/polymorphic/models.py", line 83, in save
    return super(PolymorphicModel, self).save(*args, **kwargs)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/db/models/base.py", line 807, in save
    force_update=force_update, update_fields=update_fields)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/db/models/base.py", line 847, in save_base
    update_fields=update_fields, raw=raw, using=using,
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/dispatch/dispatcher.py", line 193, in send
    for receiver in self._live_receivers(sender)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/dispatch/dispatcher.py", line 193, in <listcomp>
    for receiver in self._live_receivers(sender)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/utils/functional.py", line 15, in _curried
    return _curried_func(*(args + moreargs), **dict(kwargs, **morekwargs))
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/audit_log/middleware.py", line 69, in _update_post_save_info
    _enable_audit_log_managers(instance)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/audit_log/middleware.py", line 20, in _enable_audit_log_managers
    if isinstance(getattr(instance, attr), AuditLogManager):
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/polymorphic/models.py", line 175, in accessor_function
    attr = model._base_objects.get(pk=self.pk)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/massere/Projects/outreach-django/venv/lib/python3.5/site-packages/django/db/models/query.py", line 380, in get
    self.model._meta.object_name
outreach.models.DoesNotExist: TrainingActivity matching query does not exist.

action_user created with incorrect to= model

Hello,

I have in my Django settings file:

AUTH_USER_MODEL = 'karaage.Person'

If I try to update this model to use django-audit-log, it gives me a migration containing the following field:

('action_user', audit_log.models.fields.LastUserField(related_name='_person_audit_log_entry', editable=False, to='karaage.PersonAuditLogEntry', null=True)),

However, this is incorrect, it should point to karaage.Person, like for the other tables, eg:

('action_user', audit_log.models.fields.LastUserField(to='karaage.Person', null=True, editable=False, related_name='_projectlevel_audit_log_entry')),

This results in errors such as the following one:

  File "/home/brian/tree/karaage/karaage-working/karaage/people/models.py", line 137, in save
    super(Person, self).save(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/django/db/models/base.py", line 589, in save
    force_update=force_update, update_fields=update_fields)
  File "/usr/lib/python3/dist-packages/django/db/models/base.py", line 626, in save_base
    update_fields=update_fields, raw=raw, using=using)
  File "/usr/lib/python3/dist-packages/django/dispatch/dispatcher.py", line 198, in send
    response = receiver(signal=self, sender=sender, **named)
  File "/usr/lib/python3/dist-packages/audit_log/models/managers.py", line 107, in post_save
    self.create_log_entry(instance, created and 'I' or 'U')
  File "/usr/lib/python3/dist-packages/audit_log/models/managers.py", line 102, in create_log_entry
    manager.create(action_type = action_type, **attrs)
  File "/usr/lib/python3/dist-packages/django/db/models/manager.py", line 92, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/django/db/models/query.py", line 372, in create
    obj.save(force_insert=True, using=self.db)
  File "/usr/lib/python3/dist-packages/django/db/models/base.py", line 589, in save
    force_update=force_update, update_fields=update_fields)
  File "/usr/lib/python3/dist-packages/django/db/models/base.py", line 613, in save_base
    update_fields=update_fields)
  File "/usr/lib/python3/dist-packages/django/dispatch/dispatcher.py", line 198, in send
    response = receiver(signal=self, sender=sender, **named)
  File "/usr/lib/python3/dist-packages/django/utils/functional.py", line 17, in _curried
    return _curried_func(*(args + moreargs), **dict(kwargs, **morekwargs))
  File "/usr/lib/python3/dist-packages/audit_log/middleware.py", line 51, in _update_pre_save_info
    setattr(instance, field.name, user)
  File "/usr/lib/python3/dist-packages/django/db/models/fields/related.py", line 597, in __set__
    self.field.rel.to._meta.object_name,
ValueError: Cannot assign "<SimpleLazyObject: <Person: Test User1>>": "PersonAuditLogEntry.action_user" must be a "PersonAuditLogEntry" instance.

Any ideas?

Regards

audit_log, south and OneToOneField

Hi,
I found the problem when using OneToOneField and south.
The first migration create the field unique=True and every next migration is trying to set unique to False. And over and over.
Here is patch:

diff --git a/audit_log/models/managers.py b/audit_log/models/managers.py
index ee3defd..1c04825 100644
--- a/audit_log/models/managers.py
+++ b/audit_log/models/managers.py
@@ -101,6 +101,9 @@ class AuditLog(object):

                     field.__class__ = models.IntegerField

+                if isinstance(field, models.OneToOneField):
+                    field.__class__ = models.ForeignKey
+
                 if field.primary_key:
                     field.serialize = True

-- 
1.7.5.4

obj =form.save(commit=False) does not save the AuthStampedModel Data to obj.

        obj = form.save(commit=False)
        print("created_by: ",obj.created_by)
        print("created_with_session_key: ",obj.created_with_session_key)
        print("modified_by: ",obj.modified_by)
        print("modified_with_session_key: ",obj.modified_with_session_key)
        print("created: ",obj.created)
        print("modified: ",obj.modified)

Will always return :
created_by: None
created_with_session_key: None
modified_by: None
modified_with_session_key: None
created: None
modified: None

I may be doing something wrong but from what I've tested, this is always the case. Please let me know how to save AuthStampedModel Data during a form.save(commit=False), or allow for that functionality

Excluded fields breaks object_state

I found it necessary to use the seemingly-undocumented exclude argument to AuditLog() on a model that uses Django-MPTT, which adds some internal fields; not excluding them broke AuditLog(). However excluding them also breaks the object_state descriptor. Fix:

diff --git a/audit_log/models/managers.py b/audit_log/models/managers.py
index 50f3d47..4a9595d 100644
--- a/audit_log/models/managers.py
+++ b/audit_log/models/managers.py
@@ -13,8 +13,10 @@ class LogEntryObjectDescriptor(object):
         self.model = model

     def __get__(self, instance, owner):
-        values = (getattr(instance, f.attname) for f in self.model._meta.fields)
-        return self.model(*values)
+        kwargs = dict((f.attname, getattr(instance, f.attname))
+            for f in self.model._meta.fields
+            if hasattr(instance, f.attname))
+        return self.model(**kwargs)

 class AuditLogManager(models.Manager):
     def __init__(self, model, instance = None):
@@ -181,4 +183,4 @@ class AuditLog(object):
         attrs.update(Meta = type('Meta', (), self.get_meta_options(model)))
         name = '%sAuditLogEntry'%model._meta.object_name
         return type(name, (models.Model,), attrs)
-        
\ No newline at end of file
+          

How to supress IntegrityError while loading data from fixture

Can you please tell me how can I suppress IntegrityError

django.db.utils.IntegrityError: Problem installing fixtures: The row in table 'girvi_itemauditlogentry' with 

primary key '6372' has an invalid foreign key: girvi_itemauditlogentry.packet_id contains a value '2958' 

that does not have a corresponding value in girvi_packet.id.

Audit log queryset with filter()

Hi!

I have this query:

param = Display.audit_log.filter(campaign_id=object_id)

The query works, but in Eclipse Indigo show this error "Undefined variable from import: filter". I'm using it correctly, or is there something wrong in audit log?

Thanks!

AuditLog.create_log_entry_model() should relax foreign key restraints

If you delete a non-audited object which is referred to by an audited object's audit log entries, IntegrityErrors result. This is because create_log_entry_model() copies all fields from the original model, including the foreign key restraints.

If this is not clear, let me know and I'll try to work up a test case.

Concurrency hazards with audit-log?

I looked at the code, but I couldn't find how it isolated HTTP requests from one another.

It seems that if two requests from two users arrive at the same time, both will setup signal handlers, and receive all modifications (even those made by the other user), using the memory-global "registry" to. If so, this is a serious bug, since audit-log becomes unreliable, stuffing the wrong user into the wrong model instance.

Am I missing something ine the signal dispatching system ? Or does django-audit-log
only work with single-threaded servers?

Django 1.8 tests fail

Example error:

======================================================================
ERROR: test_fields (audit_log.tests.audit_log_tests.test_logging.TestOneToOne)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/<<PKGBUILDDIR>>/audit_log/tests/audit_log_tests/test_logging.py", line 213, in test_fields
    self.run_client(c)
  File "/<<PKGBUILDDIR>>/audit_log/tests/audit_log_tests/test_logging.py", line 206, in run_client
    client.post('/propertyowner/create/', {'name': 'John Dory'})
  File "/usr/lib/python2.7/dist-packages/django/test/client.py", line 512, in post
    secure=secure, **extra)
  File "/usr/lib/python2.7/dist-packages/django/test/client.py", line 313, in post
    secure=secure, **extra)
  File "/usr/lib/python2.7/dist-packages/django/test/client.py", line 379, in generic
    return self.request(**r)
  File "/usr/lib/python2.7/dist-packages/django/test/client.py", line 466, in request
    six.reraise(*exc_info)
  File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py", line 132, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/lib/python2.7/dist-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/django/views/generic/base.py", line 89, in dispatch
    return handler(request, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/django/views/generic/edit.py", line 249, in post
    return super(BaseCreateView, self).post(request, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/django/views/generic/edit.py", line 213, in post
    form = self.get_form()
  File "/usr/lib/python2.7/dist-packages/django/views/generic/edit.py", line 73, in get_form
    form_class = self.get_form_class()
  File "/usr/lib/python2.7/dist-packages/django/views/generic/edit.py", line 150, in get_form_class
    "the 'fields' attribute is prohibited." % self.__class__.__name__
ImproperlyConfigured: Using ModelFormMixin (base class of PropertyOwnerCreateView) without the 'fields' attribute is prohibited.

How to get log_entry.action_date value

I need to access log_entry.action_date value.
Right now I can access <Customer: XXXX deleted at 2015-01-17 19:09:48.515000+00:00> But how do I render this string into datetime value in template????? Is their way of getting access to log_entry.action_date??

Audits does not seem to be Thread safe

Hi,

I was looking for an audit log implementation and came across this project. However I do not understand why this would work in all cases. From what I understand, signals are managed and stored in memory and is the same for all threads. So if multiple requests come in at the same time you may end up with the signals from request 1 and signals from request 2 both being called for each request.

Simply put. This is not thread safe, and disconnecting and reconnecting signals at runtime is a bad idea.

Multiple MySQL database support

I've got a problem when I try to migrate an auditlogged model that isn't in the same MySQL database as the User table. It creates the table but then can't create the foreign key constraint and raises and IntegrityError

django.db.utils.IntegrityError: (1215, 'Cannot add foreign key constraint')

Tried with with Django 1.8 on Python 2.7 and Django 1.11 on Python 3.6, MySQL databases require the auditlogged model to be in the same database as the User table. SQLite databases don't have a problem here.

I've made a minimal example gist and hopefully I'm not missing something obvious.

After downloading set up virtual env

virtualenv .env
source .env/bin/activate
pip install -r pip_requirements.txt

Migration of default database

python manage.py migrate

Migrate second database with auditlogged model, raises IntegrityError

python manage.py migrate second --database=second

Python 3 support

It looks like this project wouldn't take much work to get python 3 support. I think the models.pyfile just needs from __future__ import unicode_literals, and the __unicode__ reference would need to be __str__ on python 3.

Release master to PyPi

Hi,

Any chance of doing a new release? There have been a few fixes and improvements since the beginning of last year, it would be nice to be able to install them from PyPi.

Thanks!

Django 1.10 model check issue

After upgrade to Django 1.10, you will get the following error:

check_models_permissions
max_builtin_permission_name_length = max(len(name) for name in builtin_permissions.values())
builtins.ValueError: max() arg is an empty sequence

The reason for this is because audit-log model's 'default_permissions': () [managers.py - line 239]. The problem can be fixed by change line 239 to:

result.update({'default_permissions': ('add', 'change', 'delete')})

Does this change break anything else?

Django 2.0 Support

ForeignKeys require an on_delete argument. Therefore, CreatingUserField doesn't work. Please update for Django 2.0 support.

AuditLog() ignored in abstract base classes

This is somewhat of a nuisance: If you define an audit log in an abstract base class, it is not inherited by the child class. Thus it is necessary to add audit_log to each child class. Not clear how fixable this is. May have to live with noting that it won't be inherited from abstract base classes in the usage docs, as it would probably requiring modifying Django.

Concrete Inheritance: Reverse query name for 'model.field' clashes with reverse query name for 'another_model.field'.

I have a model called Document that is concrete. I have multiple models that inherit directly from Document, such as WorkOrder(Document) and PurchaseOrder(Document). The sub classes have audit logs, and I couldn't get the audit logs to work with the parent class Document. It's okay because the PurchaseOrder and WorkOrder audit logs have a reference to the Document fields. The problem is that the Document class has two ForeignKeys with a related_name attribute set. django-audit-log does not handle them properly in its current incarnation. I suggest something along the following changes, which better correspond to Django's own related_name conventions with class and app_label:

Source in AuditLog(object):

if field.rel and field.rel.related_name:
    field.rel.related_name = '_auditlog_%s' % field.rel.related_name                
elif field.rel: 
    try:
        if field.rel.get_accessor_name():
            field.rel.related_name = '_auditlog_%s' % field.rel.get_accessor_name()
    except:
        pass

Proposed change, which does take care of the error:

if field.rel:
    format_dict = {'class': model.__name__.lower(),
                   'app_label': model._meta.app_label.lower()}
    if field.rel.related_name:
        field.rel.related_name = '_auditlog_%s' % (field.rel.related_name % format_dict)
    else:
        try:
            if field.rel.get_accessor_name():
                field.rel.related_name = '_auditlog_%s' % 
                                         (field.rel.get_accessor_name() % format_dict)
        except:
            pass

If I am handling it improperly, please let me know.

Django 1.8 compatibility

On Django 1.8, the presence of an AuditLog on a model which has foreign keys to any other model, appears to cause Django check failures regarding reverse name clashes, e.g.:

letter.Letter.sender: (fields.E304) Reverse accessor for 'Letter.sender' clashes with reverse accessor for 'Letter.sender'.
        HINT: Add or change a related_name argument to the definition for 'Letter.sender' or 'Letter.sender'.

Removing the audit log removes this error. I'm not entirely sure where to look for this bug.

audit_log did not log ManyToManyField

The audit_log did not log the many to many fields.
Django creates me a table to record the foreign keys.
example:

class registry (models.Model)
"""
other fields...
"""
Equips = models.ManyToManyField(Equipment,verbose_name ="Equipments")

django automaticly creates me a table "registry_Equips", to store multi foreignKeys for Equips

Syncdb creates the table "registry" and "table_registryauditlogentry"
But for ManyToManyField fields do not create the table "registry_Equipsauditlogentry"
only creates "registry_Equip" and i can't log changes

Makemigrations error

(env) ali@aliymn:~/portal-2.0$ python3 manage.py makemigrations
/home/ali/env/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
""")
Traceback (most recent call last):
File "manage.py", line 12, in <module>
    execute_from_command_line(sys.argv)
File "/home/ali/env/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
File "/home/ali/env/lib/python3.6/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/ali/env/lib/python3.6/site-packages/django/core/management/base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
File "/home/ali/env/lib/python3.6/site-packages/django/core/management/base.py", line 350, in execute
    self.check()
File "/home/ali/env/lib/python3.6/site-packages/django/core/management/base.py", line 379, in check
    include_deployment_checks=include_deployment_checks,
File "/home/ali/env/lib/python3.6/site-packages/django/core/management/base.py", line 366, in _run_checks
    return checks.run_checks(**kwargs)
File "/home/ali/env/lib/python3.6/site-packages/django/core/checks/registry.py", line 71, in run_checks
    new_errors = check(app_configs=app_configs)
File "/home/ali/env/lib/python3.6/site-packages/debug_toolbar/apps.py", line 34, in check_middleware
    if is_middleware_class(GZipMiddleware, middleware):
File "/home/ali/env/lib/python3.6/site-packages/debug_toolbar/apps.py", line 78, in is_middleware_class
    middleware_cls = import_string(middleware_path)
File "/home/ali/env/lib/python3.6/site-packages/django/utils/module_loading.py", line 17, in import_string
    module = import_module(module_path)
File "/home/ali/env/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/home/ali/env/lib/python3.6/site-packages/audit_log/middleware.py", line 5, in <module>
    from audit_log.models import fields
File "/home/ali/env/lib/python3.6/site-packages/audit_log/models/__init__.py", line 5, in <module>
    class AuthStampedModel(Model):
File "/home/ali/env/lib/python3.6/site-packages/audit_log/models/__init__.py", line 10, in AuthStampedModel
    created_by = CreatingUserField(verbose_name = _("created by"), related_name = "created_%(app_label)s_%(class)s_set")
File "/home/ali/env/lib/python3.6/site-packages/audit_log/models/fields.py", line 14, in __init__
    super(LastUserField, self).__init__(to = to, null = null, editable = editable, **kwargs)
TypeError: __init__() missing 1 required positional argument: 'on_delete

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.