diff options
-rw-r--r-- | archaeological_context_records/models.py | 15 | ||||
-rw-r--r-- | archaeological_finds/models_finds.py | 25 | ||||
-rw-r--r-- | archaeological_operations/tests.py | 5 | ||||
-rw-r--r-- | example_project/settings.py | 2 | ||||
-rw-r--r-- | ishtar_common/models.py | 23 | ||||
-rw-r--r-- | ishtar_common/tests.py | 2 | ||||
-rw-r--r-- | ishtar_common/utils.py | 1 |
7 files changed, 62 insertions, 11 deletions
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 678b0371d..d27c6a262 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -17,6 +17,7 @@ # See the file COPYING for details. + from django.conf import settings from django.contrib.gis.db import models from django.core.urlresolvers import reverse @@ -30,7 +31,7 @@ from ishtar_common.utils import cached_label_changed from ishtar_common.models import GeneralType, BaseHistorizedItem, \ HistoricalRecords, OwnPerms, ShortMenuItem, Source, GeneralRelationType,\ GeneralRecordRelations, post_delete_record_relation, get_external_id, \ - ImageModel, post_save_cache, ValueGetter + ImageModel, post_save_cache, ValueGetter, BulkUpdatedItem from archaeological_operations.models import Operation, Period, Parcel @@ -158,7 +159,7 @@ class CRBulkView(object): """ -class ContextRecord(BaseHistorizedItem, ImageModel, OwnPerms, +class ContextRecord(BulkUpdatedItem, BaseHistorizedItem, ImageModel, OwnPerms, ValueGetter, ShortMenuItem): SHOW_URL = 'show-contextrecord' SLUG = 'contextrecord' @@ -299,7 +300,13 @@ class ContextRecord(BaseHistorizedItem, ImageModel, OwnPerms, return self.short_label @classmethod - def cached_label_bulk_update(cls, operation_id=None, parcel_id=None): + def cached_label_bulk_update(cls, operation_id=None, parcel_id=None, + transaction_id=None): + transaction_id, is_recursion = cls.bulk_recursion( + transaction_id, [operation_id, parcel_id]) + if is_recursion: + return + if operation_id: where = "operation_id = %s" args = [int(operation_id)] @@ -310,6 +317,8 @@ class ContextRecord(BaseHistorizedItem, ImageModel, OwnPerms, kwargs = {'parcel_id': parcel_id} else: return + kwargs['transaction_id'] = transaction_id + sql = """ UPDATE "archaeological_context_records_contextrecord" AS cr SET cached_label = diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 3248e2214..da1823d8a 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -18,6 +18,7 @@ # See the file COPYING for details. import datetime +import time from django.conf import settings from django.contrib.gis.db import models @@ -36,7 +37,8 @@ from ishtar_common.models import GeneralType, ImageModel, BaseHistorizedItem, \ from archaeological_operations.models import AdministrativeAct from archaeological_context_records.models import ContextRecord, Dating -from ishtar_common.models import PRIVATE_FIELDS, SpatialReferenceSystem +from ishtar_common.models import PRIVATE_FIELDS, SpatialReferenceSystem, \ + BulkUpdatedItem class MaterialType(GeneralType): @@ -146,7 +148,7 @@ class BFBulkView(object): """ -class BaseFind(BaseHistorizedItem, OwnPerms): +class BaseFind(BulkUpdatedItem, BaseHistorizedItem, OwnPerms): label = models.TextField(_(u"Free ID")) external_id = models.TextField(_(u"External ID"), blank=True, null=True) auto_external_id = models.BooleanField( @@ -330,7 +332,12 @@ class BaseFind(BaseHistorizedItem, OwnPerms): @classmethod def cached_label_bulk_update(cls, operation_id=None, parcel_id=None, - context_record_id=None): + context_record_id=None, transaction_id=None): + transaction_id, is_recursion = cls.bulk_recursion( + transaction_id, [operation_id, parcel_id, context_record_id]) + if is_recursion: + return + if operation_id: filters = """ INNER JOIN archaeological_context_records_contextrecord acr @@ -353,6 +360,7 @@ class BaseFind(BaseHistorizedItem, OwnPerms): kwargs = {'context_record_id': context_record_id} else: return + kwargs['transaction_id'] = transaction_id sql = """ UPDATE "archaeological_finds_basefind" AS bf @@ -487,8 +495,8 @@ class FBulkView(object): """ -class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, - ShortMenuItem): +class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, ImageModel, + OwnPerms, ShortMenuItem): CHECK_DICT = dict(CHECK_CHOICES) SHOW_URL = 'show-find' SLUG = 'find' @@ -911,7 +919,12 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, @classmethod def cached_label_bulk_update(cls, operation_id=None, parcel_id=None, - context_record_id=None): + context_record_id=None, transaction_id=None): + transaction_id, is_recursion = cls.bulk_recursion( + transaction_id, [operation_id, parcel_id, context_record_id]) + if is_recursion: + return + if operation_id: filters = """ INNER JOIN find_first_base_find myfbf diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index a5b83ff1c..0b466c48c 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -25,6 +25,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.core.urlresolvers import reverse from django.test.client import Client +from django.contrib.auth.models import User from django.contrib.auth.models import Permission import models @@ -593,8 +594,12 @@ def create_operation(user, orga=None, values={}): class OperationInitTest(object): def create_user(self): username, password, self.user = create_user() + return self.user def get_default_user(self): + q = User.objects.filter(is_superuser=False) + if q.count(): + return q.all()[0] return self.create_user() def create_orgas(self, user=None): diff --git a/example_project/settings.py b/example_project/settings.py index 8241e3fca..ea7aa48fc 100644 --- a/example_project/settings.py +++ b/example_project/settings.py @@ -10,7 +10,7 @@ DEBUG_TOOLBAR = False TEMPLATE_DEBUG = DEBUG SQL_DEBUG = False DJANGO_EXTENSIONS = False -USE_SPATIALITE_FOR_TESTS = True +USE_SPATIALITE_FOR_TESTS = False TEST_VIEWS = True if "test" in sys.argv: diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 6c83c8bfb..2475cd289 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -31,6 +31,7 @@ import os import re import shutil import tempfile +import time import unicodecsv import zipfile @@ -861,6 +862,28 @@ class HistoryError(Exception): PRIVATE_FIELDS = ('id', 'history_modifier', 'order') +class BulkUpdatedItem(object): + @classmethod + def bulk_recursion(cls, transaction_id, extra_args): + """ + Prevent infinite recursion. Should not happen but wrong manipulation + in the database or messy imports can generate circular relations + + :param transaction_id: current transaction ID (unix time) - if null + a transaction ID is generated + :param extra_args: arguments dealing with + :return: (transaction ID, is a recursion) + """ + if not transaction_id: + transaction_id = unicode(time.time()) + args = ['cached_label_bulk_update', transaction_id] + extra_args + key, val = get_cache(cls, args) + if val: + return transaction_id, True + cache.set(key, 1, settings.CACHE_SMALLTIMEOUT) + return transaction_id, False + + class BaseHistorizedItem(Imported): IS_BASKET = False history_modifier = models.ForeignKey( diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py index e3958814c..eca722670 100644 --- a/ishtar_common/tests.py +++ b/ishtar_common/tests.py @@ -84,7 +84,7 @@ def create_superuser(): def create_user(): username = 'username678' - password = 'dcbqj756456!@%' + password = 'dcbqj756aaa456!@%' q = User.objects.filter(username=username) if q.count(): return username, password, q.all()[0] diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 962db5945..555a338f8 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -20,6 +20,7 @@ from functools import wraps import hashlib import random +import datetime from django import forms from django.conf import settings |