cuker / django-fullhistory Goto Github PK
View Code? Open in Web Editor NEWFullhistory for Django
Home Page: http://code.google.com/p/fullhistory/
Fullhistory for Django
Home Page: http://code.google.com/p/fullhistory/
To install: sudo setup.py install *add fullhistory middleware MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.middleware.doc.XViewMiddleware', 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', 'fullhistory.fullhistory.FullHistoryMiddleware', ) * add fullhistory to installed apps: INSTALLED_APPS = ( 'fullhistory', ) * In your models.py, select the models you want to have fullhistory: from fullhistory import register_model register_model(SKU) register_model(Order) register_model(OrderItem) Known Issues * Many to Many fields don't automatically record changes. Adjustments have been made in the admin model to compensate for this. However, changes done outside the admin that are not adjusted may exhibit a delayed recording. (Django Ticket #5390) * Files are not preserved, just their path. * (Django 1.0 only) The FullHistory field does not work as expected with Non-abstract model inheritence, primarly for objects the have inherited another's FullHistory field (Django Ticket #9546) * FullHistory truncates microseconds for DateTimeFields * DateTimeFields are deserialized as strings * Model proxies is inefficient, likely to create duplicate history entries. Will be fixed. Notes * Records for models that use Non-abstract inheritence are stored seperately per table. This has to do with the current implementation of serialization in Django. Also parent tables are capable of being independently modified of their inherited children. * Fullhistory for Non-abstract Model inheritence is slightly less performant as it follows the parental field. * QuerySet methods delete() and update() do not trigger signals and thus are outside of fullhistory * FullHistory Admin functionality is limited in Django 1.0
Thanks.
There are two ways duplicate revision numbers can be created, which causes the following error:
IntegrityError: duplicate key value violates unique constraint "fullhistory_fullhistory_revision_key"
DETAIL: Key (revision, content_type_id, object_id)=(6869, 19, 1840) already exists.
The revision number is calculated in FullHistory.save():
if not self.pk:
self.revision = len(FullHistory.objects.filter(content_type=self.content_type, object_id=self.object_id))
If another FullHistory model is inserted into the database after the revision number has been calculated, but before inserting the current model.
If old revisions are removed, for instance if your revision history becomes too large to store.
A solution for number 2 would be to find the maximum revision number and increment it:
max_revision = FullHistory.objects.filter(content_type=self.content_type, object_id=self.object_id).aggregate(rev=Max('revision'))['rev']
self.revision = (max_revision + 1) if max_revision is not None else 0
The hacky solution currently employed for number 1 is to retry with a new revision number if an IntegrityError is raised.
Traceback of the error in case it helps:
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/base.py", line 460, in save
self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/base.py", line 570, in save_base
created=(not record_exists), raw=raw, using=using)
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 172, in send
response = receiver(signal=self, sender=sender, **named)
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/fullhistory/fullhistory.py", line 124, in save_history_signal
create_history(instance, created and 'C' or 'U')
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/fullhistory/fullhistory.py", line 79, in create_history
fh.save()
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/fullhistory/models.py", line 187, in save
return super(FullHistory, self).save(*args, **kwargs)
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/base.py", line 460, in save
self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/base.py", line 553, in save_base
result = manager._insert(values, return_id=update_pk, using=using)
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/manager.py", line 195, in _insert
return insert_query(self.model, values, **kwargs)
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/query.py", line 1436, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 791, in execute_sql
cursor = super(SQLInsertCompiler, self).execute_sql(None)
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
cursor.execute(sql, params)
File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 44, in execute
return self.cursor.execute(query, args)
IntegrityError: duplicate key value violates unique constraint "fullhistory_fullhistory_revision_key"
DETAIL: Key (revision, content_type_id, object_id)=(6869, 19, 1840) already exists.
Side note: Passing a QuerySet into len will execute a query returning all matching rows. Using .count() translates into an SQL COUNT query and should be quicker.
Thanks for reading :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.