Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for changes in related models #17

Open
jjkester opened this issue Feb 16, 2015 · 3 comments
Open

Support for changes in related models #17

jjkester opened this issue Feb 16, 2015 · 3 comments

Comments

@jjkester
Copy link
Collaborator

Currently, as discovered in #8, Auditlog does not behave well when it comes to related data.

The following needs improvement:

  • Handle fixture loading (Problems with loading fixtures #8)
  • Make sure (test) that save is triggered when a reverse one-to-one relationship is changed. For example, when a different Profile object is assigned to a user from the other side of the relationship. If not, create a workaround for this.
  • Find a way to handle many-to-many relationships (easy logging for through model, easy lookup of data).
@jjkester jjkester added this to the 0.3.0 milestone Feb 16, 2015
@jjkester jjkester removed this from the 0.3.0 milestone May 15, 2015
@jjkester
Copy link
Collaborator Author

Did some research:

  • Evaluating the many-to-many relation on save() is too expensive since the list of related objects could be massive.
  • m2m_changed signal could be used but also could introduce a lot of log entries since every mutation is logged, not every transaction.
  • Setting signals on the through-model of a relation could work, there only needs to be a way to tie these log entries to the related models. (Also, this could also could introduce some log spam.)

Nice detail: the last method is currently working. Take the following example:

class MyModel(models.Model):
    related = models.ManyToManyField('MySecondaryModel')

auditlog.register(MyModel, exclude_fields['related'])  # At this point unsure whether the exclusion is mandatory
auditlog.register(MyModel.related.through)

# Get related log entries
obj = MyModel.objects.first()
rel_pks = obj.related.all().values_list('id', flat=True)
related_logentries = LogEntry.objects.get_for_model(MyModel.related.through).filter(object_id__in=rel_pks)

Parts of this example can be reworked into utility methods to make using them cleaner and more straightforward.

Ideas? Did I miss something? Please let me know!

@jjkester jjkester added this to the 0.4.0 milestone Jul 21, 2015
@jjkester jjkester modified the milestones: 0.4.0, 0.5.0 Aug 2, 2016
@jjkester
Copy link
Collaborator Author

jjkester commented Aug 2, 2016

Moved to 0.5.0 release to quickly ship improvements for Django 1.10.

@rrauenza
Copy link
Contributor

rrauenza commented Jul 1, 2020

Found another case I think of the fixture loading not working:

   Traceback (most recent call last):
    virtualenv-3.6.8/lib/python3.6/site-packages/nose/suite.py line 210 in run
      self.setUp()
    virtualenv-3.6.8/lib/python3.6/site-packages/nose/suite.py line 293 in setUp
      self.setupContext(ancestor)
    virtualenv-3.6.8/lib/python3.6/site-packages/nose/suite.py line 316 in setupContext
      try_run(context, names)
    virtualenv-3.6.8/lib/python3.6/site-packages/nose/util.py line 471 in try_run
      return func()
    perfauto/lib/testing/testcase.py line 512 in setUpClass
      return super().setUpClass()
    perfauto/lib/testing/testcase.py line 409 in setUpClass
      return super().setUpClass()
    perfauto/lib/testing/testcase.py line 394 in setUpClass
      return super().setUpClass()
    perfauto/lib/testing/testcase.py line 147 in setUpClass
      super().setUpClass()
    virtualenv-3.6.8/lib/python3.6/site-packages/django/test/testcases.py line 1131 in setUpClass
      call_command('loaddata', *cls.fixtures, **{'verbosity': 0, 'database': db_name})
    virtualenv-3.6.8/lib/python3.6/site-packages/django/core/management/__init__.py line 148 in call_command
      return command.execute(*args, **defaults)
    virtualenv-3.6.8/lib/python3.6/site-packages/django/core/management/base.py line 364 in execute
      output = self.handle(*args, **options)
    virtualenv-3.6.8/lib/python3.6/site-packages/django_nose/runner.py line 331 in _foreign_key_ignoring_handle
      _old_handle(self, *fixture_labels, **options)
    virtualenv-3.6.8/lib/python3.6/site-packages/django/core/management/commands/loaddata.py line 72 in handle
      self.loaddata(fixture_labels)
    virtualenv-3.6.8/lib/python3.6/site-packages/django/core/management/commands/loaddata.py line 114 in loaddata
      self.load_label(fixture_label)
    virtualenv-3.6.8/lib/python3.6/site-packages/django/core/management/commands/loaddata.py line 181 in load_label
      obj.save(using=self.using)
    virtualenv-3.6.8/lib/python3.6/site-packages/django/core/serializers/base.py line 223 in save
      models.Model.save_base(self.object, using=using, raw=True, **kwargs)
    virtualenv-3.6.8/lib/python3.6/site-packages/django/db/models/base.py line 790 in save_base
      update_fields=update_fields, raw=raw, using=using,
    virtualenv-3.6.8/lib/python3.6/site-packages/django/dispatch/dispatcher.py line 175 in send
      for receiver in self._live_receivers(sender)
    virtualenv-3.6.8/lib/python3.6/site-packages/django/dispatch/dispatcher.py line 175 in <listcomp>
      for receiver in self._live_receivers(sender)
    virtualenv-3.6.8/lib/python3.6/site-packages/auditlog/receivers.py line 16 in log_create
      changes = model_instance_diff(None, instance)
    virtualenv-3.6.8/lib/python3.6/site-packages/auditlog/diff.py line 135 in model_instance_diff
      new_value = get_field_value(new, field)
    virtualenv-3.6.8/lib/python3.6/site-packages/auditlog/diff.py line 80 in get_field_value
      value = field.default if field.default is not NOT_PROVIDED else None
   AttributeError: Problem installing fixture 'data.json': 'OneToOneRel' object has no attribute 'default'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants