Ejemplo n.º 1
0
    def test_nested_settings(self):
        self.assertTrue(get_setting('EXCLUDE_CHANGES'))
        excludes = get_setting('EXCLUDE_CHANGES')
        self.assertTrue(excludes['test_project.user'])

        user = self.user_model.objects.create(username='******')
        change_count = History.objects.all().count()
        user.last_login = now()
        user.save()

        self.assertEqual(History.objects.all().count(), change_count)
Ejemplo n.º 2
0
    def add(self, action, changes, model, user=None, object_id=None):
        if not getattr(settings, 'DJANGO_HISTORY_TRACK', True):
            return
        request = get_current_request()
        if not user:
            if request:
                user = request.user
        user_id = user.pk if user else None
        model_ct = ContentType.objects.get_for_model(model)
        model_id = model_ct.pk
        object_id = object_id or model.pk

        # exclusion / none -checks
        excludes = get_setting('EXCLUDE_CHANGES')
        if excludes:
            excludes_for_model = excludes.get("{0}.{1}".format(model_ct.app_label, model_ct.model))
            if excludes_for_model:
                for k,v in six.iteritems(copy.deepcopy(changes)):
                    if k in excludes_for_model.get('fields', []):
                        del changes[k]
        if not changes:
            return

        # for FKs, get old/new information
        fields = model._meta.local_fields
        def get_item(model, pk):
            value = None
            if isinstance(pk, models.Model):
                pk = copy.deepcopy(pk.pk)
            try:
                value = six.text_type(model.objects.get(pk=pk))
            except Exception as e:
                if settings.DEBUG: print(e)
            return value

        def match_field(model, changed_field):
            try:
                field = model._meta.get_field(k)
            except:
                field = model._meta.get_field(k.replace('_id', ''))
            return field

        for k,v in six.iteritems(changes):
            field = match_field(model, k)
            v['verbose_name'] = six.text_type(field.verbose_name)
            if isinstance(field, models.ForeignKey):
                parent_model = get_relation(field)
                if v['new']:
                    v['new_to_string'] = get_item(parent_model, v['new'])
                    if isinstance(v['new'], models.Model):
                        v['new'] = v['new'].pk
                if v['old']:
                    v['old_to_string'] = get_item(parent_model, v['old'])
                    if isinstance(v['old'], models.Model):
                        v['old'] = v['old'].pk
                v['is_fk'] = True
            if isinstance(field, models.ManyToManyField):
                v['is_m2m'] = True
                v['m2m_css_class'] = 'old_change'
                if 'm2m.add' in action:
                    v['m2m_css_class'] = 'new_change'
        if 'delete' in action:# M2M copied on delete
            for field in model._meta.local_many_to_many:
                pk_set = getattr(model, field.name).all()
                row = {
                    'changed': list([k.pk for k in pk_set]),
                    'is_m2m': True,
                    'm2m_css_class': 'old_change',
                    'changed_to_string': u", ".join([six.text_type(k) for k in pk_set]),
                    'verbose_name': six.text_type(field.verbose_name),
                }
                changes[field.name] = row
        changeset = {
        'fields': changes,
        'model': {
                'to_string': six.text_type(model),
                'verbose_name': six.text_type(model._meta.verbose_name),
                'content_type': {
                    'id': model_ct.pk,
                    'app_label': model_ct.app_label,
                    'model': model_ct.model,
                }
            },
        'user': {
                'to_string': six.text_type(user),
            }
        }

        history = self.model(
            action=action,
            changes=changeset,
            model=model_id,
            user=user_id,
            object_id=object_id,)
        history.save(force_insert=True)
Ejemplo n.º 3
0
from django.conf import settings
from django.middleware.csrf import get_token

from djangohistory.helpers import get_setting

_thread_locals = None
if get_setting('GET_CURRENT_REQUEST'):
    import importlib
    request_module, request_function = get_setting('GET_CURRENT_REQUEST')
    get_current_request = getattr(importlib.import_module(request_module), request_function)
else:
    import threading
    _thread_locals = threading.local()
    def get_current_request():
        return getattr(_thread_locals, 'request', None)

def reset_current_request():
    setattr(_thread_locals, 'request', None)

class ThreadLocals(object):

    def process_request(self, request):
        get_token(request) # force CSRFTOKEN setup
        _thread_locals.request = request

    def process_response(self, request, response):
        reset_current_request()
        return response