Add transaction handling in more places
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -207,6 +207,7 @@
|
|||||||
* Add a bottom margin to list links.
|
* Add a bottom margin to list links.
|
||||||
* Use copyfileobj to save documents to files
|
* Use copyfileobj to save documents to files
|
||||||
* Add user logged in and logged out events.
|
* Add user logged in and logged out events.
|
||||||
|
* Add transaction handling in more places.
|
||||||
|
|
||||||
3.1.11 (2019-04-XX)
|
3.1.11 (2019-04-XX)
|
||||||
===================
|
===================
|
||||||
|
|||||||
@@ -239,6 +239,8 @@ Other changes
|
|||||||
* Add a bottom margin to list links.
|
* Add a bottom margin to list links.
|
||||||
* Use copyfileobj to save documents to files
|
* Use copyfileobj to save documents to files
|
||||||
* Add user logged in and logged out events.
|
* Add user logged in and logged out events.
|
||||||
|
* Add transaction handling in more places: Checkouts, documents,
|
||||||
|
metadata, tags.
|
||||||
|
|
||||||
Removals
|
Removals
|
||||||
--------
|
--------
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from __future__ import absolute_import, unicode_literals
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.db import models
|
from django.db import models, transaction
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
|
|
||||||
from mayan.apps.documents.models import Document
|
from mayan.apps.documents.models import Document
|
||||||
@@ -33,17 +33,18 @@ class DocumentCheckoutManager(models.Manager):
|
|||||||
except self.model.DoesNotExist:
|
except self.model.DoesNotExist:
|
||||||
raise DocumentNotCheckedOut
|
raise DocumentNotCheckedOut
|
||||||
else:
|
else:
|
||||||
if user:
|
with transaction.atomic():
|
||||||
if self.get_check_out_info(document=document).user != user:
|
if user:
|
||||||
event_document_forceful_check_in.commit(
|
if self.get_check_out_info(document=document).user != user:
|
||||||
actor=user, target=document
|
event_document_forceful_check_in.commit(
|
||||||
)
|
actor=user, target=document
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
event_document_check_in.commit(actor=user, target=document)
|
||||||
else:
|
else:
|
||||||
event_document_check_in.commit(actor=user, target=document)
|
event_document_auto_check_in.commit(target=document)
|
||||||
else:
|
|
||||||
event_document_auto_check_in.commit(target=document)
|
|
||||||
|
|
||||||
document_check_out.delete()
|
document_check_out.delete()
|
||||||
|
|
||||||
def check_in_expired_check_outs(self):
|
def check_in_expired_check_outs(self):
|
||||||
for document in self.expired_check_outs():
|
for document in self.expired_check_outs():
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import logging
|
|||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models, transaction
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_text, python_2_unicode_compatible
|
from django.utils.encoding import force_text, python_2_unicode_compatible
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
@@ -65,9 +65,9 @@ class DocumentCheckout(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
# TODO: enclose in transaction
|
with transaction.atomic():
|
||||||
NewVersionBlock.objects.unblock(document=self.document)
|
NewVersionBlock.objects.unblock(document=self.document)
|
||||||
super(DocumentCheckout, self).delete(*args, **kwargs)
|
super(DocumentCheckout, self).delete(*args, **kwargs)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse(
|
return reverse(
|
||||||
@@ -81,25 +81,25 @@ class DocumentCheckout(models.Model):
|
|||||||
natural_key.dependencies = ['documents.Document']
|
natural_key.dependencies = ['documents.Document']
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
# TODO: enclose in transaction
|
|
||||||
new_checkout = not self.pk
|
new_checkout = not self.pk
|
||||||
if not new_checkout or self.document.is_checked_out():
|
if not new_checkout or self.document.is_checked_out():
|
||||||
raise DocumentAlreadyCheckedOut
|
raise DocumentAlreadyCheckedOut
|
||||||
|
|
||||||
result = super(DocumentCheckout, self).save(*args, **kwargs)
|
with transaction.atomic():
|
||||||
if new_checkout:
|
result = super(DocumentCheckout, self).save(*args, **kwargs)
|
||||||
event_document_check_out.commit(
|
if new_checkout:
|
||||||
actor=self.user, target=self.document
|
event_document_check_out.commit(
|
||||||
)
|
actor=self.user, target=self.document
|
||||||
if self.block_new_version:
|
)
|
||||||
NewVersionBlock.objects.block(self.document)
|
if self.block_new_version:
|
||||||
|
NewVersionBlock.objects.block(self.document)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
'Document "%s" checked out by user "%s"',
|
'Document "%s" checked out by user "%s"',
|
||||||
self.document, self.user
|
self.document, self.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class NewVersionBlock(models.Model):
|
class NewVersionBlock(models.Model):
|
||||||
|
|||||||
@@ -250,9 +250,12 @@ class DocumentVersion(models.Model):
|
|||||||
self.document, self
|
self.document, self
|
||||||
)
|
)
|
||||||
|
|
||||||
event_document_version_revert.commit(actor=_user, target=self.document)
|
with transaction.atomic():
|
||||||
for version in self.document.versions.filter(timestamp__gt=self.timestamp):
|
event_document_version_revert.commit(
|
||||||
version.delete()
|
actor=_user, target=self.document
|
||||||
|
)
|
||||||
|
for version in self.document.versions.filter(timestamp__gt=self.timestamp):
|
||||||
|
version.delete()
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from __future__ import unicode_literals
|
|||||||
import shlex
|
import shlex
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models, transaction
|
||||||
from django.template import Context, Template
|
from django.template import Context, Template
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_text, python_2_unicode_compatible
|
from django.utils.encoding import force_text, python_2_unicode_compatible
|
||||||
@@ -97,7 +97,11 @@ class MetadataType(models.Model):
|
|||||||
return self.label
|
return self.label
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('metadata:setup_metadata_type_edit', args=(self.pk,))
|
return reverse(
|
||||||
|
viewname='metadata:setup_metadata_type_edit', kwargs={
|
||||||
|
'pk': self.pk
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if PY2:
|
if PY2:
|
||||||
# Python 2 non unicode version
|
# Python 2 non unicode version
|
||||||
@@ -141,21 +145,22 @@ class MetadataType(models.Model):
|
|||||||
return (self.name,)
|
return (self.name,)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
user = kwargs.pop('_user', None)
|
_user = kwargs.pop('_user', None)
|
||||||
created = not self.pk
|
created = not self.pk
|
||||||
|
|
||||||
result = super(MetadataType, self).save(*args, **kwargs)
|
with transaction.atomic():
|
||||||
|
result = super(MetadataType, self).save(*args, **kwargs)
|
||||||
|
|
||||||
if created:
|
if created:
|
||||||
event_metadata_type_created.commit(
|
event_metadata_type_created.commit(
|
||||||
actor=user, target=self
|
actor=_user, target=self
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
event_metadata_type_edited.commit(
|
event_metadata_type_edited.commit(
|
||||||
actor=user, target=self
|
actor=_user, target=self
|
||||||
)
|
)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def validate_value(self, document_type, value):
|
def validate_value(self, document_type, value):
|
||||||
# Check default
|
# Check default
|
||||||
@@ -234,13 +239,15 @@ class DocumentMetadata(models.Model):
|
|||||||
_('Metadata type is required for this document type.')
|
_('Metadata type is required for this document type.')
|
||||||
)
|
)
|
||||||
|
|
||||||
user = kwargs.pop('_user', None)
|
_user = kwargs.pop('_user', None)
|
||||||
result = super(DocumentMetadata, self).delete(*args, **kwargs)
|
with transaction.atomic():
|
||||||
|
result = super(DocumentMetadata, self).delete(*args, **kwargs)
|
||||||
|
|
||||||
event_document_metadata_removed.commit(
|
event_document_metadata_removed.commit(
|
||||||
action_object=self.metadata_type, actor=user, target=self.document,
|
action_object=self.metadata_type, actor=_user,
|
||||||
)
|
target=self.document,
|
||||||
return result
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
def natural_key(self):
|
def natural_key(self):
|
||||||
return self.document.natural_key() + self.metadata_type.natural_key()
|
return self.document.natural_key() + self.metadata_type.natural_key()
|
||||||
@@ -262,23 +269,24 @@ class DocumentMetadata(models.Model):
|
|||||||
_('Metadata type is not valid for this document type.')
|
_('Metadata type is not valid for this document type.')
|
||||||
)
|
)
|
||||||
|
|
||||||
user = kwargs.pop('_user', None)
|
_user = kwargs.pop('_user', None)
|
||||||
created = not self.pk
|
created = not self.pk
|
||||||
|
|
||||||
result = super(DocumentMetadata, self).save(*args, **kwargs)
|
with transaction.atomic():
|
||||||
|
result = super(DocumentMetadata, self).save(*args, **kwargs)
|
||||||
|
|
||||||
if created:
|
if created:
|
||||||
event_document_metadata_added.commit(
|
event_document_metadata_added.commit(
|
||||||
action_object=self.metadata_type, actor=user,
|
action_object=self.metadata_type, actor=_user,
|
||||||
target=self.document,
|
target=self.document,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
event_document_metadata_edited.commit(
|
event_document_metadata_edited.commit(
|
||||||
action_object=self.metadata_type, actor=user,
|
action_object=self.metadata_type, actor=_user,
|
||||||
target=self.document,
|
target=self.document,
|
||||||
)
|
)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
@@ -309,23 +317,27 @@ class DocumentTypeMetadataType(models.Model):
|
|||||||
return force_text(self.metadata_type)
|
return force_text(self.metadata_type)
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
user = kwargs.pop('_user', None)
|
_user = kwargs.pop('_user', None)
|
||||||
|
|
||||||
result = super(DocumentTypeMetadataType, self).delete(*args, **kwargs)
|
with transaction.atomic():
|
||||||
|
result = super(DocumentTypeMetadataType, self).delete(*args, **kwargs)
|
||||||
|
|
||||||
event_metadata_type_relationship.commit(
|
event_metadata_type_relationship.commit(
|
||||||
action_object=self.document_type, actor=user, target=self.metadata_type,
|
action_object=self.document_type, actor=_user,
|
||||||
)
|
target=self.metadata_type,
|
||||||
|
)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
user = kwargs.pop('_user', None)
|
_user = kwargs.pop('_user', None)
|
||||||
|
|
||||||
result = super(DocumentTypeMetadataType, self).save(*args, **kwargs)
|
with transaction.atomic():
|
||||||
|
result = super(DocumentTypeMetadataType, self).save(*args, **kwargs)
|
||||||
|
|
||||||
event_metadata_type_relationship.commit(
|
event_metadata_type_relationship.commit(
|
||||||
action_object=self.document_type, actor=user, target=self.metadata_type,
|
action_object=self.document_type, actor=_user,
|
||||||
)
|
target=self.metadata_type,
|
||||||
|
)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models, transaction
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
@@ -83,17 +83,18 @@ class Tag(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
user = kwargs.pop('_user', None)
|
_user = kwargs.pop('_user', None)
|
||||||
created = not self.pk
|
created = not self.pk
|
||||||
|
|
||||||
result = super(Tag, self).save(*args, **kwargs)
|
with transaction.atomic():
|
||||||
|
result = super(Tag, self).save(*args, **kwargs)
|
||||||
|
|
||||||
if created:
|
if created:
|
||||||
event_tag_created.commit(actor=user, target=self)
|
event_tag_created.commit(actor=_user, target=self)
|
||||||
else:
|
else:
|
||||||
event_tag_edited.commit(actor=user, target=self)
|
event_tag_edited.commit(actor=_user, target=self)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class DocumentTag(Tag):
|
class DocumentTag(Tag):
|
||||||
|
|||||||
Reference in New Issue
Block a user