diff options
Diffstat (limited to 'django-simple-history/simple_history')
6 files changed, 0 insertions, 467 deletions
diff --git a/django-simple-history/simple_history/__init__.py b/django-simple-history/simple_history/__init__.py deleted file mode 100755 index 6df0b60b6..000000000 --- a/django-simple-history/simple_history/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -import models - - -registered_models = {} - - -def register(model, app=None, manager_name='history'): -    """ -    Create historical model for `model` and attach history manager to `model`. - -    Keyword arguments: -    app -- App to install historical model into (defaults to model.__module__) -    manager_name -- class attribute name to use for historical manager - -    This method should be used as an alternative to attaching an -    `HistoricalManager` instance directly to `model`. -    """ -    if not model in registered_models: -        records = models.HistoricalRecords() -        records.manager_name = manager_name -        records.module = ("%s.models" % app) or model.__module__ -        records.finalize(model) diff --git a/django-simple-history/simple_history/admin.py b/django-simple-history/simple_history/admin.py deleted file mode 100644 index 7d83e1016..000000000 --- a/django-simple-history/simple_history/admin.py +++ /dev/null @@ -1,139 +0,0 @@ -from django import template -from django.core.exceptions import PermissionDenied -from django.conf.urls.defaults import patterns, url -from django.contrib import admin -from django.contrib.admin import helpers -from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse -from django.shortcuts import get_object_or_404, render_to_response -from django.contrib.admin.util import unquote -from django.utils.text import capfirst -from django.utils.html import mark_safe -from django.utils.translation import ugettext as _ -from django.utils.encoding import force_unicode - - -class SimpleHistoryAdmin(admin.ModelAdmin): -    object_history_template = "simple_history/object_history.html" -    object_history_form_template = "simple_history/object_history_form.html" - -    def get_urls(self): -        """Returns the additional urls used by the Reversion admin.""" -        urls = super(SimpleHistoryAdmin, self).get_urls() -        admin_site = self.admin_site -        opts = self.model._meta -        info = opts.app_label, opts.module_name, -        history_urls = patterns("", -            url("^([^/]+)/history/([^/]+)/$", -                admin_site.admin_view(self.history_form_view), -                name='%s_%s_simple_history' % info),) -        return history_urls + urls - -    def history_view(self, request, object_id, extra_context=None): -        "The 'history' admin view for this model." -        model = self.model -        opts = model._meta -        app_label = opts.app_label -        pk_name = opts.pk.attname -        history = getattr(model, model._meta.simple_history_manager_attribute) -        action_list = history.filter(**{pk_name: object_id}) -        # If no history was found, see whether this object even exists. -        obj = get_object_or_404(model, pk=unquote(object_id)) -        context = { -            'title': _('Change history: %s') % force_unicode(obj), -            'action_list': action_list, -            'module_name': capfirst(force_unicode(opts.verbose_name_plural)), -            'object': obj, -            'root_path': getattr(self.admin_site, 'root_path', None), -            'app_label': app_label, -            'opts': opts -        } -        context.update(extra_context or {}) -        context_instance = template.RequestContext(request, current_app=self.admin_site.name) -        return render_to_response(self.object_history_template, context, context_instance=context_instance) - -    def history_form_view(self, request, object_id, version_id): -        original_model = self.model -        original_opts = original_model._meta -        history = getattr(self.model, self.model._meta.simple_history_manager_attribute) -        model = history.model -        opts = model._meta -        pk_name = original_opts.pk.attname -        record = get_object_or_404(model, **{pk_name: object_id, 'history_id': version_id}) -        obj = record.instance -        obj._state.adding = False - -        if not self.has_change_permission(request, obj): -            raise PermissionDenied - -        if request.method == 'POST' and '_saveas_new' in request.POST: -            return self.add_view(request, form_url='../add/') - -        formsets = [] -        ModelForm = self.get_form(request, obj) -        if request.method == 'POST': -            form = ModelForm(request.POST, request.FILES, instance=obj) -            if form.is_valid(): -                form_validated = True -                new_object = self.save_form(request, form, change=True) -            else: -                form_validated = False -                new_object = obj -            prefixes = {} - -            if form_validated: -                self.save_model(request, new_object, form, change=True) -                form.save_m2m() - -                change_message = self.construct_change_message(request, form, formsets) -                self.log_change(request, new_object, change_message) -                return self.response_change(request, new_object) - -        else: -            form = ModelForm(instance=obj) - -        adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), -            self.prepopulated_fields, self.get_readonly_fields(request, obj), -            model_admin=self) -        media = self.media + adminForm.media - -        url_triplet = (self.admin_site.name, original_opts.app_label, -                            original_opts.module_name) -        context = { -            'title': _('Revert %s') % force_unicode(obj), -            'adminform': adminForm, -            'object_id': object_id, -            'original': obj, -            'is_popup': False, -            'media': mark_safe(media), -            'errors': helpers.AdminErrorList(form, formsets), -            'app_label': opts.app_label, -            'original_opts': original_opts, -            'changelist_url': reverse('%s:%s_%s_changelist' % url_triplet), -            'change_url': reverse('%s:%s_%s_change' % url_triplet, args=(obj.pk,)), -            'history_url': reverse('%s:%s_%s_history' % url_triplet, args=(obj.pk,)), -            # Context variables copied from render_change_form -            'add': False, -            'change': True, -            'has_add_permission': self.has_add_permission(request), -            'has_change_permission': self.has_change_permission(request, obj), -            'has_delete_permission': self.has_delete_permission(request, obj), -            'has_file_field': True, -            'has_absolute_url': False, -            'ordered_objects': opts.get_ordered_objects(), -            'form_url': '', -            'opts': opts, -            'content_type_id': ContentType.objects.get_for_model(self.model).id, -            'save_as': self.save_as, -            'save_on_top': self.save_on_top, -            'root_path': getattr(self.admin_site, 'root_path', None), -        } -        context_instance = template.RequestContext(request, current_app=self.admin_site.name) -        return render_to_response(self.object_history_form_template, context, context_instance) - -    def save_model(self, request, obj, form, change): -        """ -        Add the admin user to a special model attribute for reference after save -        """ -        obj._history_user = request.user -        super(SimpleHistoryAdmin, self).save_model(request, obj, form, change) diff --git a/django-simple-history/simple_history/manager.py b/django-simple-history/simple_history/manager.py deleted file mode 100755 index 923b310eb..000000000 --- a/django-simple-history/simple_history/manager.py +++ /dev/null @@ -1,75 +0,0 @@ -from django.db import models - - -class HistoryDescriptor(object): -    def __init__(self, model): -        self.model = model - -    def __get__(self, instance, owner): -        if instance is None: -            return HistoryManager(self.model) -        return HistoryManager(self.model, instance) - - -class HistoryManager(models.Manager): -    def __init__(self, model, instance=None): -        super(HistoryManager, self).__init__() -        self.model = model -        self.instance = instance - -    def get_query_set(self): -        if self.instance is None: -            return super(HistoryManager, self).get_query_set() - -        if isinstance(self.instance._meta.pk, models.OneToOneField): -            filter = {self.instance._meta.pk.name + "_id": self.instance.pk} -        else: -            filter = {self.instance._meta.pk.name: self.instance.pk} -        return super(HistoryManager, self).get_query_set().filter(**filter) - -    def most_recent(self): -        """ -        Returns the most recent copy of the instance available in the history. -        """ -        if not self.instance: -            raise TypeError("Can't use most_recent() without a %s instance." % -                            self.instance._meta.object_name) -        tmp = [] -        for field in self.instance._meta.fields: -            if isinstance(field, models.ForeignKey): -                tmp.append(field.name + "_id") -            else: -                tmp.append(field.name) -        fields = tuple(tmp) -        try: -            values = self.values_list(*fields)[0] -        except IndexError: -            raise self.instance.DoesNotExist("%s has no historical record." % -                                             self.instance._meta.object_name) -        return self.instance.__class__(*values) - -    def as_of(self, date): -        """ -        Returns an instance of the original model with all the attributes set -        according to what was present on the object on the date provided. -        """ -        if not self.instance: -            raise TypeError("Can't use as_of() without a %s instance." % -                            self.instance._meta.object_name) -        tmp = [] -        for field in self.instance._meta.fields: -            if isinstance(field, models.ForeignKey): -                tmp.append(field.name + "_id") -            else: -                tmp.append(field.name) -        fields = tuple(tmp) -        qs = self.filter(history_date__lte=date) -        try: -            values = qs.values_list('history_type', *fields)[0] -        except IndexError: -            raise self.instance.DoesNotExist("%s had not yet been created." % -                                             self.instance._meta.object_name) -        if values[0] == '-': -            raise self.instance.DoesNotExist("%s had already been deleted." % -                                             self.instance._meta.object_name) -        return self.instance.__class__(*values[1:]) diff --git a/django-simple-history/simple_history/models.py b/django-simple-history/simple_history/models.py deleted file mode 100644 index 06054ba34..000000000 --- a/django-simple-history/simple_history/models.py +++ /dev/null @@ -1,169 +0,0 @@ -import copy -from django.db import models -from django.contrib import admin -from django.contrib.auth.models import User -from django.utils import importlib -from manager import HistoryDescriptor - - -class HistoricalRecords(object): -    def contribute_to_class(self, cls, name): -        self.manager_name = name -        self.module = cls.__module__ -        models.signals.class_prepared.connect(self.finalize, sender=cls) - -        def save_without_historical_record(self, *args, **kwargs): -            """Caution! Make sure you know what you're doing before you use this method.""" -            self.skip_history_when_saving = True -            ret = self.save(*args, **kwargs) -            del self.skip_history_when_saving -            return ret -        setattr(cls, 'save_without_historical_record', save_without_historical_record) - -    def finalize(self, sender, **kwargs): -        history_model = self.create_history_model(sender) -        module = importlib.import_module(self.module) -        setattr(module, history_model.__name__, history_model) - -        # The HistoricalRecords object will be discarded, -        # so the signal handlers can't use weak references. -        models.signals.post_save.connect(self.post_save, sender=sender, -                                         weak=False) -        models.signals.post_delete.connect(self.post_delete, sender=sender, -                                           weak=False) - -        descriptor = HistoryDescriptor(history_model) -        setattr(sender, self.manager_name, descriptor) -        sender._meta.simple_history_manager_attribute = self.manager_name - -    def create_history_model(self, model): -        """ -        Creates a historical model to associate with the model provided. -        """ -        attrs = {'__module__': self.module} - -        fields = self.copy_fields(model) -        attrs.update(fields) -        attrs.update(self.get_extra_fields(model, fields)) -        attrs.update(Meta=type('Meta', (), self.get_meta_options(model))) -        name = 'Historical%s' % model._meta.object_name -        return type(name, (models.Model,), attrs) - -    def copy_fields(self, model): -        """ -        Creates copies of the model's original fields, returning -        a dictionary mapping field name to copied field object. -        """ -        fields = {} - -        for field in model._meta.fields: -            field = copy.copy(field) -            fk = None - -            if isinstance(field, models.AutoField): -                # The historical model gets its own AutoField, so any -                # existing one must be replaced with an IntegerField. -                field.__class__ = models.IntegerField - -            if isinstance(field, models.ForeignKey): -                field.__class__ = models.IntegerField -                #ughhhh. open to suggestions here -                try: -                    field.rel = None -                except: -                    pass -                try: -                    field.related = None -                except: -                    pass -                try: -                    field.related_query_name = None -                except: -                    pass -                field.null = True -                field.blank = True -                fk = True -            else: -                fk = False - -            # The historical instance should not change creation/modification timestamps. -            field.auto_now = False -            field.auto_now_add = False - -            if field.primary_key or field.unique: -                # Unique fields can no longer be guaranteed unique, -                # but they should still be indexed for faster lookups. -                field.primary_key = False -                field._unique = False -                field.db_index = True -                field.serialize = True -            if fk: -                field.name = field.name + "_id" -            fields[field.name] = field - -        return fields - -    def get_extra_fields(self, model, fields): -        """ -        Returns a dictionary of fields that will be added to the historical -        record model, in addition to the ones returned by copy_fields below. -        """ -        @models.permalink -        def revert_url(self): -            opts = model._meta -            return ('%s:%s_%s_simple_history' % -                    (admin.site.name, opts.app_label, opts.module_name), -                    [getattr(self, opts.pk.attname), self.history_id]) -        def get_instance(self): -            return model(**dict([(k, getattr(self, k)) for k in fields])) - -        return { -            'history_id': models.AutoField(primary_key=True), -            'history_date': models.DateTimeField(auto_now_add=True), -            'history_user': models.ForeignKey(User, null=True), -            'history_type': models.CharField(max_length=1, choices=( -                ('+', 'Created'), -                ('~', 'Changed'), -                ('-', 'Deleted'), -            )), -            'history_object': HistoricalObjectDescriptor(model), -            'instance': property(get_instance), -            'revert_url': revert_url, -            '__unicode__': lambda self: u'%s as of %s' % (self.history_object, -                                                          self.history_date) -        } - -    def get_meta_options(self, model): -        """ -        Returns a dictionary of fields that will be added to -        the Meta inner class of the historical record model. -        """ -        return { -            'ordering': ('-history_date', '-history_id'), -        } - -    def post_save(self, instance, created, **kwargs): -        if not created and hasattr(instance, 'skip_history_when_saving'): -            return -        if not kwargs.get('raw', False): -            self.create_historical_record(instance, created and '+' or '~') - -    def post_delete(self, instance, **kwargs): -        self.create_historical_record(instance, '-') - -    def create_historical_record(self, instance, type): -        history_user = getattr(instance, '_history_user', None) -        manager = getattr(instance, self.manager_name) -        attrs = {} -        for field in instance._meta.fields: -            attrs[field.attname] = getattr(instance, field.attname) -        manager.create(history_type=type, history_user=history_user, **attrs) - - -class HistoricalObjectDescriptor(object): -    def __init__(self, model): -        self.model = model - -    def __get__(self, instance, owner): -        values = (getattr(instance, f.attname) for f in self.model._meta.fields) -        return self.model(*values) diff --git a/django-simple-history/simple_history/templates/simple_history/object_history.html b/django-simple-history/simple_history/templates/simple_history/object_history.html deleted file mode 100644 index d14338232..000000000 --- a/django-simple-history/simple_history/templates/simple_history/object_history.html +++ /dev/null @@ -1,38 +0,0 @@ -{% extends "admin/object_history.html" %} -{% load i18n %} - - -{% block content %} -	<div id="content-main"> - -		<p>{% blocktrans %}Choose a date from the list below to revert to a previous version of this object.{% endblocktrans %}</p> - -		<div class="module"> -			{% if action_list %} -				<table id="change-history"> -					<thead> -						<tr> -							<th scope="col">{% trans 'Object' %}</th> -							<th scope="col">{% trans 'Date/time' %}</th> -							<th scope="col">{% trans 'Comment' %}</th> -							<th scope="col">{% trans 'Changed by' %}</th> -						</tr> -					</thead> -					<tbody> -						{% for action in action_list %} -							<tr> -								<td><a href="{{ action.revert_url }}">{{ action.history_object }}</a></td> -								<td>{{ action.history_date }}</td> -								<td>{{ action.get_history_type_display }}</td> -								<td><a href="{% url admin:auth_user_change action.history_user_id %}">{{ action.history_user }}</a></td> -							</tr> -						{% endfor %} -					</tbody> -				</table> -			{% else %} -				<p>{% trans "This object doesn't have a change history." %}</p> -			{% endif %} -		</div> -	</div> -{% endblock %} - diff --git a/django-simple-history/simple_history/templates/simple_history/object_history_form.html b/django-simple-history/simple_history/templates/simple_history/object_history_form.html deleted file mode 100644 index fdc8f1a87..000000000 --- a/django-simple-history/simple_history/templates/simple_history/object_history_form.html +++ /dev/null @@ -1,24 +0,0 @@ -{% extends "admin/change_form.html" %} -{% load i18n %} - -{% block breadcrumbs %} -	<div class="breadcrumbs"> -		<a href="{% url admin:index %}">{% trans "Home" %}</a> › -		<a href="{% url admin:app_list app_label %}">{{app_label|capfirst|escape}}</a> › -		<a href="{{changelist_url}}">{{opts.verbose_name_plural|capfirst}}</a> › -		<a href="{{change_url}}">{{original|truncatewords:"18"}}</a> › -		<a href="../">{% trans "History" %}</a> › -		{% blocktrans with original_opts.verbose_name as verbose_name %}Revert {{verbose_name}}{% endblocktrans %} -	</div> -{% endblock %} - -{% comment %}Hack to remove "Save as New" and "Save and Continue" buttons {% endcomment %} -{% block content %} -	{% with 1 as is_popup %} -		{{block.super}} -	{% endwith %} -{% endblock %} - -{% block form_top %} -	<p>{% blocktrans %}Press the save button below to revert to this version of the object.{% endblocktrans %}</p> -{% endblock %}  | 
