summaryrefslogtreecommitdiff
path: root/archaeological_context_records/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'archaeological_context_records/models.py')
-rw-r--r--archaeological_context_records/models.py873
1 files changed, 526 insertions, 347 deletions
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py
index 2c43ad810..02d488c85 100644
--- a/archaeological_context_records/models.py
+++ b/archaeological_context_records/models.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2012-2017 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
@@ -28,23 +28,47 @@ from django.core.urlresolvers import reverse
from django.db import connection
from django.db.models import Q
from django.db.models.signals import post_delete, post_save, m2m_changed
-from ishtar_common.utils import ugettext_lazy as _,\
- pgettext_lazy, pgettext
+from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy, pgettext
from django.utils.text import slugify
-from ishtar_common.utils import cached_label_changed, \
- m2m_historization_changed, post_save_geo
-
-from ishtar_common.models import Document, GeneralType, \
- BaseHistorizedItem, OwnPerms, ShortMenuItem, \
- GeneralRelationType, GeneralRecordRelations, post_delete_record_relation,\
- post_save_cache, ValueGetter, BulkUpdatedItem, \
- RelationItem, Town, get_current_profile, document_attached_changed, \
- HistoryModel, SearchAltName, GeoItem, CompleteIdentifierItem, SearchVectorConfig, \
- DocumentItem, MainItem, QuickAction
+from ishtar_common.utils import (
+ cached_label_changed,
+ m2m_historization_changed,
+ post_save_geo,
+)
+
+from ishtar_common.models import (
+ Document,
+ GeneralType,
+ BaseHistorizedItem,
+ OwnPerms,
+ ShortMenuItem,
+ GeneralRelationType,
+ GeneralRecordRelations,
+ post_delete_record_relation,
+ post_save_cache,
+ ValueGetter,
+ BulkUpdatedItem,
+ RelationItem,
+ Town,
+ get_current_profile,
+ document_attached_changed,
+ HistoryModel,
+ SearchAltName,
+ GeoItem,
+ CompleteIdentifierItem,
+ SearchVectorConfig,
+ DocumentItem,
+ MainItem,
+ QuickAction,
+)
from ishtar_common.models_common import HistoricalRecords
-from archaeological_operations.models import Operation, Period, Parcel, \
- ArchaeologicalSite
+from archaeological_operations.models import (
+ Operation,
+ Period,
+ Parcel,
+ ArchaeologicalSite,
+)
from ishtar_common.model_managers import UUIDModelManager
@@ -52,7 +76,7 @@ class DatingType(GeneralType):
class Meta:
verbose_name = _("Dating type")
verbose_name_plural = _("Dating types")
- ordering = ('label',)
+ ordering = ("label",)
post_save.connect(post_save_cache, sender=DatingType)
@@ -63,7 +87,7 @@ class DatingQuality(GeneralType):
class Meta:
verbose_name = _("Dating quality type")
verbose_name_plural = _("Dating quality types")
- ordering = ('label',)
+ ordering = ("label",)
post_save.connect(post_save_cache, sender=DatingQuality)
@@ -75,48 +99,55 @@ class Dating(models.Model):
period = models.ForeignKey(Period, verbose_name=_("Period"))
start_date = models.IntegerField(_("Start date"), blank=True, null=True)
end_date = models.IntegerField(_("End date"), blank=True, null=True)
- dating_type = models.ForeignKey(DatingType, verbose_name=_("Dating type"),
- on_delete=models.SET_NULL,
- blank=True, null=True)
- quality = models.ForeignKey(DatingQuality, verbose_name=_("Quality"),
- on_delete=models.SET_NULL,
- blank=True, null=True)
- precise_dating = models.TextField(
- _("Precise dating"), blank=True, default="")
+ dating_type = models.ForeignKey(
+ DatingType,
+ verbose_name=_("Dating type"),
+ on_delete=models.SET_NULL,
+ blank=True,
+ null=True,
+ )
+ quality = models.ForeignKey(
+ DatingQuality,
+ verbose_name=_("Quality"),
+ on_delete=models.SET_NULL,
+ blank=True,
+ null=True,
+ )
+ precise_dating = models.TextField(_("Precise dating"), blank=True, default="")
objects = UUIDModelManager()
ASSOCIATED_ALT_NAMES = {
- 'datings__period': SearchAltName(
+ "datings__period": SearchAltName(
pgettext_lazy("key for text search", "datings-period"),
- 'datings__period__label__iexact'
+ "datings__period__label__iexact",
),
"datings__precise_dating": SearchAltName(
pgettext_lazy("key for text search", "datings-precise"),
- 'datings__precise_dating__iexact'
+ "datings__precise_dating__iexact",
),
"datings__start_date__before": SearchAltName(
pgettext_lazy("key for text search", "datings-start-before"),
- 'datings__start_date__lte'
+ "datings__start_date__lte",
),
"datings__start_date__after": SearchAltName(
pgettext_lazy("key for text search", "datings-start-after"),
- 'datings__start_date__gte'
+ "datings__start_date__gte",
),
"datings__end_date__before": SearchAltName(
pgettext_lazy("key for text search", "datings-end-before"),
- 'datings__end_date__lte'
+ "datings__end_date__lte",
),
"datings__end_date__after": SearchAltName(
pgettext_lazy("key for text search", "datings-end-after"),
- 'datings__end_date__gte'
+ "datings__end_date__gte",
),
"datings__dating_type": SearchAltName(
pgettext_lazy("key for text search", "datings-type"),
- 'datings__dating_type__label__iexact'
+ "datings__dating_type__label__iexact",
),
"datings__quality": SearchAltName(
pgettext_lazy("key for text search", "datings-quality"),
- 'datings__quality__label__iexact'
- )
+ "datings__quality__label__iexact",
+ ),
}
class Meta:
@@ -133,39 +164,45 @@ class Dating(models.Model):
return "%s (%s-%s)" % (self.period, start_date, end_date)
def natural_key(self):
- return self.uuid,
+ return (self.uuid,)
- def get_values(self, prefix='', no_values=False, filtr=None, **kwargs):
+ def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
values = {}
if not filtr or prefix + "period" in filtr:
values[prefix + "period"] = str(self.period)
if not filtr or prefix + "start_date" in filtr:
- values[prefix + "start_date"] = self.start_date or ''
+ values[prefix + "start_date"] = self.start_date or ""
if not filtr or prefix + "end_date" in filtr:
- values[prefix + "end_date"] = self.end_date or ''
+ values[prefix + "end_date"] = self.end_date or ""
if not filtr or prefix + "dating_type" in filtr:
- values[prefix + "dating_type"] = \
+ values[prefix + "dating_type"] = (
str(self.dating_type) if self.dating_type else ""
+ )
if not filtr or prefix + "quality" in filtr:
- values[prefix + "quality"] = \
- str(self.quality) if self.quality else ""
+ values[prefix + "quality"] = str(self.quality) if self.quality else ""
if not filtr or prefix + "precise_dating" in filtr:
values[prefix + "precise_dating"] = self.precise_dating
return values
- HISTORY_ATTR = ["period", "start_date", "end_date", "dating_type",
- "quality", "precise_dating"]
+ HISTORY_ATTR = [
+ "period",
+ "start_date",
+ "end_date",
+ "dating_type",
+ "quality",
+ "precise_dating",
+ ]
def history_compress(self):
values = {}
for attr in self.HISTORY_ATTR:
val = getattr(self, attr)
- if hasattr(val, 'history_compress'):
+ if hasattr(val, "history_compress"):
val = val.history_compress()
- elif hasattr(val, 'isoformat'):
+ elif hasattr(val, "isoformat"):
val = val.isoformat()
elif val is None:
- val = ''
+ val = ""
else:
val = str(val)
values[attr] = val
@@ -180,7 +217,7 @@ class Dating(models.Model):
res = {}
for key in value:
val = value[key]
- if val == '' and key != "precise_dating":
+ if val == "" and key != "precise_dating":
val = None
elif key in ("period", "dating_type", "quality"):
field = cls._meta.get_field(key)
@@ -203,8 +240,14 @@ class Dating(models.Model):
Compare two dating attribute by attribute and return True if all
attribute is identical
"""
- for attr in ["period", "start_date", "end_date", "dating_type",
- "quality", "precise_dating"]:
+ for attr in [
+ "period",
+ "start_date",
+ "end_date",
+ "dating_type",
+ "quality",
+ "precise_dating",
+ ]:
value1 = getattr(dating_1, attr)
value2 = getattr(dating_2, attr)
if attr == "precise_dating":
@@ -218,11 +261,13 @@ class Dating(models.Model):
def context_records_lbl(self):
return " - ".join(cr.cached_label for cr in self.context_records.all())
+
context_records_lbl.short_description = _("Context record")
context_records_lbl.admin_order_field = "context_records__cached_label"
def finds_lbl(self):
return " - ".join(f.cached_label for f in self.find.all())
+
finds_lbl.short_description = _("Find")
finds_lbl.admin_order_field = "find__cached_label"
@@ -232,9 +277,15 @@ class Dating(models.Model):
Fix redundant m2m dating association (usually after imports)
"""
current_datings = []
- for dating in obj.datings.order_by('pk').all():
- key = (dating.period.pk, dating.start_date, dating.end_date,
- dating.dating_type, dating.quality, dating.precise_dating)
+ for dating in obj.datings.order_by("pk").all():
+ key = (
+ dating.period.pk,
+ dating.start_date,
+ dating.end_date,
+ dating.dating_type,
+ dating.quality,
+ dating.precise_dating,
+ )
if key not in current_datings:
current_datings.append(key)
continue
@@ -244,13 +295,17 @@ class Dating(models.Model):
class Unit(GeneralType):
order = models.IntegerField(_("Order"))
parent = models.ForeignKey(
- "Unit", verbose_name=_("Parent context record type"),
- on_delete=models.SET_NULL, blank=True, null=True)
+ "Unit",
+ verbose_name=_("Parent context record type"),
+ on_delete=models.SET_NULL,
+ blank=True,
+ null=True,
+ )
class Meta:
verbose_name = _("Context record Type")
verbose_name_plural = _("Context record Types")
- ordering = ('order', 'label')
+ ordering = ("order", "label")
def __str__(self):
return self.label
@@ -266,7 +321,7 @@ class ActivityType(GeneralType):
class Meta:
verbose_name = _("Activity Type")
verbose_name_plural = _("Activity Types")
- ordering = ('order',)
+ ordering = ("order",)
def __str__(self):
return self.label
@@ -282,7 +337,7 @@ class IdentificationType(GeneralType):
class Meta:
verbose_name = _("Identification Type")
verbose_name_plural = _("Identification Types")
- ordering = ('order', 'label')
+ ordering = ("order", "label")
def __str__(self):
return self.label
@@ -296,7 +351,7 @@ class ExcavationTechnicType(GeneralType):
class Meta:
verbose_name = _("Excavation technique type")
verbose_name_plural = _("Excavation technique types")
- ordering = ('label',)
+ ordering = ("label",)
post_save.connect(post_save_cache, sender=ExcavationTechnicType)
@@ -307,7 +362,7 @@ class DocumentationType(GeneralType):
class Meta:
verbose_name = _("Documentation type")
verbose_name_plural = _("Documentation types")
- ordering = ('label',)
+ ordering = ("label",)
post_save.connect(post_save_cache, sender=DocumentationType)
@@ -334,138 +389,152 @@ class CRBulkView(object):
"""
-class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
- CompleteIdentifierItem, GeoItem, OwnPerms, ValueGetter, MainItem,
- RelationItem):
- SLUG = 'contextrecord'
+class ContextRecord(
+ BulkUpdatedItem,
+ DocumentItem,
+ BaseHistorizedItem,
+ CompleteIdentifierItem,
+ GeoItem,
+ OwnPerms,
+ ValueGetter,
+ MainItem,
+ RelationItem,
+):
+ SLUG = "contextrecord"
APP = "archaeological-context-records"
MODEL = "context-record"
- SHOW_URL = 'show-contextrecord'
- DELETE_URL = 'delete-contextrecord'
- EXTERNAL_ID_KEY = 'context_record_external_id'
- EXTERNAL_ID_DEPENDENCIES = ['base_finds']
- TABLE_COLS = ['label', 'operation__common_name', 'town__name',
- 'parcel__cached_label', 'unit__label']
- if settings.COUNTRY == 'fr':
- TABLE_COLS.insert(1, 'operation__code_patriarche')
- TABLE_COLS_FOR_OPE = ['label', 'parcel__cached_label', 'unit__label',
- 'cached_periods', 'description']
+ SHOW_URL = "show-contextrecord"
+ DELETE_URL = "delete-contextrecord"
+ EXTERNAL_ID_KEY = "context_record_external_id"
+ EXTERNAL_ID_DEPENDENCIES = ["base_finds"]
+ TABLE_COLS = [
+ "label",
+ "operation__common_name",
+ "town__name",
+ "parcel__cached_label",
+ "unit__label",
+ ]
+ if settings.COUNTRY == "fr":
+ TABLE_COLS.insert(1, "operation__code_patriarche")
+ TABLE_COLS_FOR_OPE = [
+ "label",
+ "parcel__cached_label",
+ "unit__label",
+ "cached_periods",
+ "description",
+ ]
NEW_QUERY_ENGINE = True
COL_LABELS = {
- 'cached_periods': _("Periods"),
- 'datings__period__label': _("Periods"),
- 'datings__period': _("Datings (period)"),
- 'detailed_related_context_records': _("Related context records"),
+ "cached_periods": _("Periods"),
+ "datings__period__label": _("Periods"),
+ "datings__period": _("Datings (period)"),
+ "detailed_related_context_records": _("Related context records"),
"cached_related_context_records": _("Related context records"),
- 'operation__code_patriarche': _("Operation (Patriarche code)"),
- 'operation__common_name': _("Operation (name)"),
- 'parcel__external_id': _("Parcel (external ID)"),
- 'town__name': _("Town"),
- 'town': _("Town"),
- 'parcel__year': _("Parcel (year)"),
- 'section__parcel_number': _("Parcel"),
- 'parcel__cached_label': _("Parcel"),
- 'unit__label': _("Context record type"),
+ "operation__code_patriarche": _("Operation (Patriarche code)"),
+ "operation__common_name": _("Operation (name)"),
+ "parcel__external_id": _("Parcel (external ID)"),
+ "town__name": _("Town"),
+ "town": _("Town"),
+ "parcel__year": _("Parcel (year)"),
+ "section__parcel_number": _("Parcel"),
+ "parcel__cached_label": _("Parcel"),
+ "unit__label": _("Context record type"),
}
CONTEXTUAL_TABLE_COLS = {
- 'full': {
- 'related_context_records': 'cached_related_context_records'
- }
+ "full": {"related_context_records": "cached_related_context_records"}
}
# statistics
- STATISTIC_MODALITIES_OPTIONS = OrderedDict([
- ("unit__label", _("Context record type")),
- ("datings__period__label", _("Period")),
- ("identification__label", _("Identification")),
- ("activity__label", _("Activity")),
- ("excavation_technic__label", _("Excavation technique")),
- ("documents__source_type__label", _("Associated document type")),
- ])
- STATISTIC_MODALITIES = [
- key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()]
+ STATISTIC_MODALITIES_OPTIONS = OrderedDict(
+ [
+ ("unit__label", _("Context record type")),
+ ("datings__period__label", _("Period")),
+ ("identification__label", _("Identification")),
+ ("activity__label", _("Activity")),
+ ("excavation_technic__label", _("Excavation technique")),
+ ("documents__source_type__label", _("Associated document type")),
+ ]
+ )
+ STATISTIC_MODALITIES = [key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()]
# search parameters
EXTRA_REQUEST_KEYS = {
- 'town': 'town__pk',
- 'town__name': 'town__name',
- 'parcel__cached_label': 'parcel__cached_label',
- 'operation__year': 'operation__year__contains',
- 'year': 'operation__year__contains',
- 'operation__code_patriarche': 'operation__code_patriarche',
- 'operation__operation_code': 'operation__operation_code',
- 'operation__common_name': 'operation__common_name',
- 'datings__period': 'datings__period__pk',
- 'parcel_0': 'operation__parcels__section',
- 'parcel_1': 'operation__parcels__parcel_number',
- 'parcel_2': 'operation__parcels__public_domain',
- 'label': 'label__icontains',
- 'archaeological_sites': 'operation__archaeological_sites__pk',
- 'cached_label': 'cached_label__icontains',
- 'datings__period__label': 'datings__period__label',
- 'operation_id': 'operation_id',
- 'unit__label': "unit__label",
+ "town": "town__pk",
+ "town__name": "town__name",
+ "parcel__cached_label": "parcel__cached_label",
+ "operation__year": "operation__year__contains",
+ "year": "operation__year__contains",
+ "operation__code_patriarche": "operation__code_patriarche",
+ "operation__operation_code": "operation__operation_code",
+ "operation__common_name": "operation__common_name",
+ "datings__period": "datings__period__pk",
+ "parcel_0": "operation__parcels__section",
+ "parcel_1": "operation__parcels__parcel_number",
+ "parcel_2": "operation__parcels__public_domain",
+ "label": "label__icontains",
+ "archaeological_sites": "operation__archaeological_sites__pk",
+ "cached_label": "cached_label__icontains",
+ "datings__period__label": "datings__period__label",
+ "operation_id": "operation_id",
+ "unit__label": "unit__label",
}
- MANY_COUNTED_FIELDS = ['base_finds']
+ MANY_COUNTED_FIELDS = ["base_finds"]
REVERSED_BOOL_FIELDS = [
- 'documents__image__isnull',
- 'documents__associated_file__isnull',
- 'documents__associated_url__isnull',
+ "documents__image__isnull",
+ "documents__associated_file__isnull",
+ "documents__associated_url__isnull",
]
- RELATION_TYPES_PREFIX = {'ope_relation_types': 'operation__',
- 'cr_relation_types': ''}
+ RELATION_TYPES_PREFIX = {
+ "ope_relation_types": "operation__",
+ "cr_relation_types": "",
+ }
# alternative names of fields for searches
ALT_NAMES = {
- 'label': SearchAltName(
- pgettext_lazy("key for text search", "id"),
- 'label__iexact'
+ "label": SearchAltName(
+ pgettext_lazy("key for text search", "id"), "label__iexact"
),
- 'town': SearchAltName(
- pgettext_lazy("key for text search", "town"),
- 'town__cached_label__iexact'
+ "town": SearchAltName(
+ pgettext_lazy("key for text search", "town"), "town__cached_label__iexact"
),
- 'operation__year': SearchAltName(
- pgettext_lazy("key for text search", "operation-year"),
- 'operation__year'
+ "operation__year": SearchAltName(
+ pgettext_lazy("key for text search", "operation-year"), "operation__year"
),
- 'operation__code_patriarche': SearchAltName(
+ "operation__code_patriarche": SearchAltName(
pgettext_lazy("key for text search", "patriarche"),
- 'operation__code_patriarche__iexact'
+ "operation__code_patriarche__iexact",
),
- 'operation__operation_code': SearchAltName(
+ "operation__operation_code": SearchAltName(
pgettext_lazy("key for text search", "operation-code"),
- 'operation__operation_code'
+ "operation__operation_code",
),
- 'operation__cached_label': SearchAltName(
+ "operation__cached_label": SearchAltName(
pgettext_lazy("key for text search", "operation"),
- 'operation__cached_label__icontains'
+ "operation__cached_label__icontains",
),
- 'archaeological_site': SearchAltName(
+ "archaeological_site": SearchAltName(
pgettext_lazy("key for text search", "site"),
- 'archaeological_site__cached_label__icontains'
+ "archaeological_site__cached_label__icontains",
),
- 'ope_relation_types': SearchAltName(
+ "ope_relation_types": SearchAltName(
pgettext_lazy("key for text search", "operation-relation-type"),
- 'ope_relation_types'
+ "ope_relation_types",
),
- 'datings__period': SearchAltName(
+ "datings__period": SearchAltName(
pgettext_lazy("key for text search", "period"),
- 'datings__period__label__iexact'
+ "datings__period__label__iexact",
),
- 'unit': SearchAltName(
- pgettext_lazy("key for text search", "unit-type"),
- 'unit__label__iexact'
+ "unit": SearchAltName(
+ pgettext_lazy("key for text search", "unit-type"), "unit__label__iexact"
),
- 'parcel': SearchAltName(
+ "parcel": SearchAltName(
pgettext_lazy("key for text search", "parcel"),
- 'parcel__cached_label__iexact'
+ "parcel__cached_label__iexact",
),
- 'has_finds': SearchAltName(
- pgettext_lazy("key for text search", "has-finds"),
- 'base_finds'
+ "has_finds": SearchAltName(
+ pgettext_lazy("key for text search", "has-finds"), "base_finds"
),
- 'cr_relation_types': SearchAltName(
+ "cr_relation_types": SearchAltName(
pgettext_lazy("key for text search", "record-relation-type"),
- 'cr_relation_types'
+ "cr_relation_types",
),
}
ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES)
@@ -478,47 +547,47 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
SearchVectorConfig("label"),
SearchVectorConfig("location"),
SearchVectorConfig("town__name"),
- SearchVectorConfig("interpretation", 'local'),
- SearchVectorConfig("filling", 'local'),
- SearchVectorConfig("datings_comment", 'local'),
+ SearchVectorConfig("interpretation", "local"),
+ SearchVectorConfig("filling", "local"),
+ SearchVectorConfig("datings_comment", "local"),
SearchVectorConfig("identification__label"),
SearchVectorConfig("activity__label"),
- SearchVectorConfig("excavation_technic__label")]
- M2M_SEARCH_VECTORS = [
- SearchVectorConfig("datings__period__label", 'local')
+ SearchVectorConfig("excavation_technic__label"),
]
+ M2M_SEARCH_VECTORS = [SearchVectorConfig("datings__period__label", "local")]
UP_MODEL_QUERY = {
"operation": (
pgettext_lazy("key for text search", "operation"),
- 'cached_label'),
- "site": (
- pgettext_lazy("key for text search", "site"),
- 'cached_label'),
+ "cached_label",
+ ),
+ "site": (pgettext_lazy("key for text search", "site"), "cached_label"),
}
MAIN_UP_MODEL_QUERY = "operation"
RELATIVE_SESSION_NAMES = [
- ('operation', 'operation__pk'),
- ('site', 'archaeological_site__pk'),
- ('file', 'operation__associated_file__pk'),
- ]
- HISTORICAL_M2M = [
- 'datings', 'documentations'
+ ("operation", "operation__pk"),
+ ("site", "archaeological_site__pk"),
+ ("file", "operation__associated_file__pk"),
]
- CACHED_LABELS = ['cached_label', 'cached_periods',
- "cached_related_context_records"]
+ HISTORICAL_M2M = ["datings", "documentations"]
+ CACHED_LABELS = ["cached_label", "cached_periods", "cached_related_context_records"]
DOWN_MODEL_UPDATE = ["base_finds"]
QA_LOCK = QuickAction(
- url="contextrecord-qa-lock", icon_class="fa fa-lock",
- text=_("Lock/Unlock"), target="many",
- rights=['change_contextrecord', 'change_own_contextrecord']
+ url="contextrecord-qa-lock",
+ icon_class="fa fa-lock",
+ text=_("Lock/Unlock"),
+ target="many",
+ rights=["change_contextrecord", "change_own_contextrecord"],
)
QUICK_ACTIONS = [
QA_LOCK,
QuickAction(
- url="contextrecord-qa-duplicate", icon_class="fa fa-clone",
- text=_("Duplicate"), target="one",
- rights=['change_contextrecord', 'change_own_contextrecord']),
+ url="contextrecord-qa-duplicate",
+ icon_class="fa fa-clone",
+ text=_("Duplicate"),
+ target="one",
+ rights=["change_contextrecord", "change_own_contextrecord"],
+ ),
]
history = HistoricalRecords(bases=[HistoryModel])
@@ -528,91 +597,150 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
uuid = models.UUIDField(default=uuid.uuid4)
external_id = models.TextField(_("External ID"), blank=True, default="")
auto_external_id = models.BooleanField(
- _("External ID is set automatically"), default=False)
+ _("External ID is set automatically"), default=False
+ )
parcel = models.ForeignKey(
- Parcel, verbose_name=_("Parcel"), related_name='context_record',
- on_delete=models.SET_NULL, blank=True, null=True)
+ Parcel,
+ verbose_name=_("Parcel"),
+ related_name="context_record",
+ on_delete=models.SET_NULL,
+ blank=True,
+ null=True,
+ )
town = models.ForeignKey(
- Town, verbose_name=_("Town"), related_name='context_record',
- on_delete=models.SET_NULL, blank=True, null=True)
- operation = models.ForeignKey(Operation, verbose_name=_("Operation"),
- related_name='context_record')
+ Town,
+ verbose_name=_("Town"),
+ related_name="context_record",
+ on_delete=models.SET_NULL,
+ blank=True,
+ null=True,
+ )
+ operation = models.ForeignKey(
+ Operation, verbose_name=_("Operation"), related_name="context_record"
+ )
archaeological_site = models.ForeignKey(
- ArchaeologicalSite, verbose_name=_("Archaeological site"),
+ ArchaeologicalSite,
+ verbose_name=_("Archaeological site"),
on_delete=models.SET_NULL,
- blank=True, null=True, related_name='context_records')
+ blank=True,
+ null=True,
+ related_name="context_records",
+ )
label = models.CharField(_("ID"), max_length=200)
description = models.TextField(_("Description"), blank=True, default="")
comment = models.TextField(_("General comment"), blank=True, default="")
- opening_date = models.DateField(_("Opening date"),
- blank=True, null=True)
+ opening_date = models.DateField(_("Opening date"), blank=True, null=True)
closing_date = models.DateField(_("Closing date"), blank=True, null=True)
length = models.FloatField(_("Length (m)"), blank=True, null=True)
width = models.FloatField(_("Width (m)"), blank=True, null=True)
- thickness = models.FloatField(_("Thickness (m)"), blank=True,
- null=True)
+ thickness = models.FloatField(_("Thickness (m)"), blank=True, null=True)
diameter = models.FloatField(_("Diameter (m)"), blank=True, null=True)
depth = models.FloatField(_("Depth (m)"), blank=True, null=True)
depth_of_appearance = models.FloatField(
- _("Depth of appearance (m)"), blank=True, null=True)
+ _("Depth of appearance (m)"), blank=True, null=True
+ )
surface = models.IntegerField(_("Surface (m2)"), blank=True, null=True)
location = models.TextField(
- _("Location"), blank=True, default="",
- help_text=_("A short description of the location of the context "
- "record"))
- datings = models.ManyToManyField(Dating, related_name='context_records')
+ _("Location"),
+ blank=True,
+ default="",
+ help_text=_("A short description of the location of the context " "record"),
+ )
+ datings = models.ManyToManyField(Dating, related_name="context_records")
documentations = models.ManyToManyField(DocumentationType, blank=True)
- datings_comment = models.TextField(
- _("Comment on datings"), blank=True, default="")
- unit = models.ForeignKey(Unit, verbose_name=_("Context record type"),
- on_delete=models.SET_NULL,
- related_name='+', blank=True, null=True)
+ datings_comment = models.TextField(_("Comment on datings"), blank=True, default="")
+ unit = models.ForeignKey(
+ Unit,
+ verbose_name=_("Context record type"),
+ on_delete=models.SET_NULL,
+ related_name="+",
+ blank=True,
+ null=True,
+ )
filling = models.TextField(_("Filling"), blank=True, default="")
- interpretation = models.TextField(
- _("Interpretation"), blank=True, default="")
+ interpretation = models.TextField(_("Interpretation"), blank=True, default="")
taq = models.IntegerField(
- _("TAQ"), blank=True, null=True,
- help_text=_("\"Terminus Ante Quem\" the context record can't have "
- "been created after this date"))
+ _("TAQ"),
+ blank=True,
+ null=True,
+ help_text=_(
+ '"Terminus Ante Quem" the context record can\'t have '
+ "been created after this date"
+ ),
+ )
taq_estimated = models.IntegerField(
- _("Estimated TAQ"), blank=True, null=True,
- help_text=_("Estimation of a \"Terminus Ante Quem\""))
+ _("Estimated TAQ"),
+ blank=True,
+ null=True,
+ help_text=_('Estimation of a "Terminus Ante Quem"'),
+ )
tpq = models.IntegerField(
- _("TPQ"), blank=True, null=True,
- help_text=_("\"Terminus Post Quem\" the context record can't have "
- "been created before this date"))
+ _("TPQ"),
+ blank=True,
+ null=True,
+ help_text=_(
+ '"Terminus Post Quem" the context record can\'t have '
+ "been created before this date"
+ ),
+ )
tpq_estimated = models.IntegerField(
- _("Estimated TPQ"), blank=True, null=True,
- help_text=_("Estimation of a \"Terminus Post Quem\""))
+ _("Estimated TPQ"),
+ blank=True,
+ null=True,
+ help_text=_('Estimation of a "Terminus Post Quem"'),
+ )
identification = models.ForeignKey(
- IdentificationType, blank=True, null=True,
+ IdentificationType,
+ blank=True,
+ null=True,
on_delete=models.SET_NULL,
- verbose_name=_("Identification"),)
- activity = models.ForeignKey(ActivityType, blank=True, null=True,
- on_delete=models.SET_NULL,
- verbose_name=_("Activity"),)
+ verbose_name=_("Identification"),
+ )
+ activity = models.ForeignKey(
+ ActivityType,
+ blank=True,
+ null=True,
+ on_delete=models.SET_NULL,
+ verbose_name=_("Activity"),
+ )
excavation_technic = models.ForeignKey(
- ExcavationTechnicType, blank=True, null=True,
+ ExcavationTechnicType,
+ blank=True,
+ null=True,
on_delete=models.SET_NULL,
- verbose_name=_("Excavation technique"))
+ verbose_name=_("Excavation technique"),
+ )
related_context_records = models.ManyToManyField(
- 'ContextRecord', through='RecordRelations', blank=True)
+ "ContextRecord", through="RecordRelations", blank=True
+ )
documents = models.ManyToManyField(
- Document, related_name='context_records', verbose_name=_("Documents"),
- blank=True)
+ Document,
+ related_name="context_records",
+ verbose_name=_("Documents"),
+ blank=True,
+ )
main_image = models.ForeignKey(
- Document, related_name='main_image_context_records',
+ Document,
+ related_name="main_image_context_records",
on_delete=models.SET_NULL,
- verbose_name=_("Main image"), blank=True, null=True)
- cached_label = models.TextField(_("Cached name"), blank=True, default="",
- db_index=True)
- cached_periods = models.TextField(
- _("Cached periods label"), blank=True, default="",
- help_text=_("Generated automatically - do not edit")
+ verbose_name=_("Main image"),
+ blank=True,
+ null=True,
+ )
+ cached_label = models.TextField(
+ _("Cached name"), blank=True, default="", db_index=True
+ )
+ cached_periods = models.TextField(
+ _("Cached periods label"),
+ blank=True,
+ default="",
+ help_text=_("Generated automatically - do not edit"),
)
cached_related_context_records = models.TextField(
- _("Cached related context records"), blank=True, default="",
- help_text=_("Generated automatically - do not edit")
+ _("Cached related context records"),
+ blank=True,
+ default="",
+ help_text=_("Generated automatically - do not edit"),
)
class Meta:
@@ -625,13 +753,13 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
("change_own_contextrecord", "Can change own Context Record"),
("delete_own_contextrecord", "Can delete own Context Record"),
)
- ordering = ('cached_label',)
+ ordering = ("cached_label",)
indexes = [
- GinIndex(fields=['data']),
+ GinIndex(fields=["data"]),
]
def natural_key(self):
- return (self.uuid, )
+ return (self.uuid,)
@property
def name(self):
@@ -651,36 +779,39 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
def public_representation(self):
dct = super(ContextRecord, self).public_representation()
- dct.update({
- "operation": self.operation.public_representation(),
- "site": self.archaeological_site and
- self.archaeological_site.public_representation(),
- "parcel": str(self.parcel),
- "town": self.town.label_with_areas if self.town else None,
- "label": self.label,
- "description": self.description,
- "comment": self.comment
- })
+ dct.update(
+ {
+ "operation": self.operation.public_representation(),
+ "site": self.archaeological_site
+ and self.archaeological_site.public_representation(),
+ "parcel": str(self.parcel),
+ "town": self.town.label_with_areas if self.town else None,
+ "label": self.label,
+ "description": self.description,
+ "comment": self.comment,
+ }
+ )
return dct
DOC_VALUES = [
("base_finds", _("List of associated base finds")),
]
- def get_values(self, prefix='', no_values=False, filtr=None, **kwargs):
+ def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
no_base_finds = True
if "no_base_finds" in kwargs:
no_base_finds = kwargs["no_base_finds"]
values = super(ContextRecord, self).get_values(
- prefix=prefix, no_values=no_values, filtr=filtr, **kwargs)
+ prefix=prefix, no_values=no_values, filtr=filtr, **kwargs
+ )
if prefix and no_base_finds:
return values
- if not filtr or prefix + 'base_finds' in filtr:
- values[prefix + 'base_finds'] = [
- bf.get_values(
- prefix=prefix, no_values=True, filtr=None, **kwargs)
- for bf in self.base_finds.distinct().all()]
+ if not filtr or prefix + "base_finds" in filtr:
+ values[prefix + "base_finds"] = [
+ bf.get_values(prefix=prefix, no_values=True, filtr=None, **kwargs)
+ for bf in self.base_finds.distinct().all()
+ ]
return values
def get_town_centroid(self):
@@ -722,24 +853,26 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
return self.operation.get_precise_polygons()
@classmethod
- def cached_label_bulk_update(cls, operation_id=None, parcel_id=None,
- transaction_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])
+ transaction_id, [operation_id, parcel_id]
+ )
if is_recursion:
return
if operation_id:
where = "operation_id = %s"
args = [int(operation_id)]
- kwargs = {'operation_id': operation_id}
+ kwargs = {"operation_id": operation_id}
elif parcel_id:
where = "parcel_id = %s"
args = [int(parcel_id)]
- kwargs = {'parcel_id': parcel_id}
+ kwargs = {"parcel_id": parcel_id}
else:
return
- kwargs['transaction_id'] = transaction_id
+ kwargs["transaction_id"] = transaction_id
profile = get_current_profile()
@@ -776,18 +909,27 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
SELECT id FROM archaeological_context_records_contextrecord
WHERE {where}
);
- """.format(main_ope_prefix=profile.operation_prefix,
- ope_prefix=profile.default_operation_prefix,
- join=settings.JOINT, where=where)
+ """.format(
+ main_ope_prefix=profile.operation_prefix,
+ ope_prefix=profile.default_operation_prefix,
+ join=settings.JOINT,
+ where=where,
+ )
with connection.cursor() as c:
c.execute(sql, args)
- cls._meta.get_field(
- 'base_finds').related_model.cached_label_bulk_update(**kwargs)
+ cls._meta.get_field("base_finds").related_model.cached_label_bulk_update(
+ **kwargs
+ )
@property
def short_label(self):
- return settings.JOINT.join([str(item) for item in [
- self.operation.get_reference(), self.parcel, self.label] if item])
+ return settings.JOINT.join(
+ [
+ str(item)
+ for item in [self.operation.get_reference(), self.parcel, self.label]
+ if item
+ ]
+ )
@property
def relation_label(self):
@@ -796,49 +938,66 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
def all_base_finds(self):
BaseFind = apps.get_model("archaeological_finds", "BaseFind")
ids = [self.id] + [
- cr.cr_id for cr in ContextRecordTree.objects.filter(
- cr_parent_id=self.id)]
+ cr.cr_id for cr in ContextRecordTree.objects.filter(cr_parent_id=self.id)
+ ]
return BaseFind.objects.filter(context_record_id__in=ids)
@property
def show_url(self):
- return reverse('show-contextrecord', args=[self.pk, ''])
+ return reverse("show-contextrecord", args=[self.pk, ""])
def get_extra_actions(self, request):
# url, base_text, icon, extra_text, extra css class, is a quick action
actions = super(ContextRecord, self).get_extra_actions(request)
- #is_locked = hasattr(self, "is_locked") and self.is_locked(request.user)
- can_edit_cr = self.can_do(request, 'change_contextrecord')
+ # is_locked = hasattr(self, "is_locked") and self.is_locked(request.user)
+ can_edit_cr = self.can_do(request, "change_contextrecord")
if can_edit_cr:
actions += [
- (reverse("contextrecord-qa-duplicate", args=[self.pk]),
- _("Duplicate"), "fa fa-clone", "", "", True),
+ (
+ reverse("contextrecord-qa-duplicate", args=[self.pk]),
+ _("Duplicate"),
+ "fa fa-clone",
+ "",
+ "",
+ True,
+ ),
]
return actions
@classmethod
def get_query_owns(cls, ishtaruser):
- return cls._construct_query_own(
- 'operation__', Operation._get_query_owns_dicts(ishtaruser)
- ) | cls._construct_query_own(
- 'base_finds__find__basket__',
- [{"shared_with": ishtaruser, "shared_write_with": ishtaruser}]
- ) | cls._construct_query_own('', [
- {'history_creator': ishtaruser.user_ptr},
- {'operation__end_date__isnull': True}
- ])
+ return (
+ cls._construct_query_own(
+ "operation__", Operation._get_query_owns_dicts(ishtaruser)
+ )
+ | cls._construct_query_own(
+ "base_finds__find__basket__",
+ [{"shared_with": ishtaruser, "shared_write_with": ishtaruser}],
+ )
+ | cls._construct_query_own(
+ "",
+ [
+ {"history_creator": ishtaruser.user_ptr},
+ {"operation__end_date__isnull": True},
+ ],
+ )
+ )
@classmethod
- def get_owns(cls, user, menu_filtr=None, limit=None,
- values=None, get_short_menu_class=None):
+ def get_owns(
+ cls, user, menu_filtr=None, limit=None, values=None, get_short_menu_class=None
+ ):
replace_query = None
- if menu_filtr and 'operation' in menu_filtr:
- replace_query = Q(operation=menu_filtr['operation'])
+ if menu_filtr and "operation" in menu_filtr:
+ replace_query = Q(operation=menu_filtr["operation"])
owns = super(ContextRecord, cls).get_owns(
- user, replace_query=replace_query,
- limit=limit, values=values,
- get_short_menu_class=get_short_menu_class)
+ user,
+ replace_query=replace_query,
+ limit=limit,
+ values=values,
+ get_short_menu_class=get_short_menu_class,
+ )
return cls._return_get_owns(owns, values, get_short_menu_class)
def full_label(self):
@@ -847,15 +1006,22 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
def _real_label(self):
if not self.operation.code_patriarche:
return
- return settings.JOINT.join((self.operation.code_patriarche,
- self.label))
+ return settings.JOINT.join((self.operation.code_patriarche, self.label))
def _temp_label(self):
if self.operation.code_patriarche:
return
- return settings.JOINT.join([str(lbl) for lbl in [
- self.operation.year, self.operation.operation_code, self.label]
- if lbl])
+ return settings.JOINT.join(
+ [
+ str(lbl)
+ for lbl in [
+ self.operation.year,
+ self.operation.operation_code,
+ self.label,
+ ]
+ if lbl
+ ]
+ )
def _generate_cached_label(self):
return self.full_label()
@@ -869,17 +1035,18 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
def _get_associated_cached_labels(self):
BaseFind = apps.get_model("archaeological_finds", "BaseFind")
Find = apps.get_model("archaeological_finds", "Find")
- return list(Find.objects.filter(base_finds__context_record=self).all())\
- + list(BaseFind.objects.filter(context_record=self).all())
+ return list(Find.objects.filter(base_finds__context_record=self).all()) + list(
+ BaseFind.objects.filter(context_record=self).all()
+ )
def _cached_labels_bulk_update(self):
- self.base_finds.model.cached_label_bulk_update(
- context_record_id=self.pk)
+ self.base_finds.model.cached_label_bulk_update(context_record_id=self.pk)
return True
def _get_base_image_path(self):
- return self.operation._get_base_image_path() + \
- "/{}/{}".format(self.SLUG, slugify(self.label or "00"))
+ return self.operation._get_base_image_path() + "/{}/{}".format(
+ self.SLUG, slugify(self.label or "00")
+ )
@property
def archaeological_site_reference(self):
@@ -887,7 +1054,8 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
return self.archaeological_site.reference
if self.operation.archaeological_sites.count():
return "-".join(
- a.reference for a in self.operation.archaeological_sites.all())
+ a.reference for a in self.operation.archaeological_sites.all()
+ )
return ""
@property
@@ -907,15 +1075,15 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
return self.operation.get_town_label()
@classmethod
- def get_periods(cls, slice='year', fltr={}):
+ def get_periods(cls, slice="year", fltr={}):
q = cls.objects
if fltr:
q = q.filter(**fltr)
- if slice == 'year':
+ if slice == "year":
years = set()
- for res in list(q.values('operation__start_date')):
- if res['operation__start_date']:
- yr = res['operation__start_date'].year
+ for res in list(q.values("operation__start_date")):
+ if res["operation__start_date"]:
+ yr = res["operation__start_date"].year
years.add(yr)
return list(years)
return []
@@ -929,8 +1097,10 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
@classmethod
def get_operations(cls):
- return [dct['operation__pk']
- for dct in cls.objects.values('operation__pk').distinct()]
+ return [
+ dct["operation__pk"]
+ for dct in cls.objects.values("operation__pk").distinct()
+ ]
@classmethod
def get_by_operation(cls, operation_id):
@@ -963,7 +1133,8 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
def save(self, *args, **kwargs):
super(ContextRecord, self).save(*args, **kwargs)
if (not self.town and self.parcel) or (
- self.parcel and self.parcel.town != self.town):
+ self.parcel and self.parcel.town != self.town
+ ):
self.town = self.parcel.town
self.skip_history_when_saving = True
self.save()
@@ -975,40 +1146,44 @@ def context_record_post_save(sender, **kwargs):
post_save.connect(context_record_post_save, sender=ContextRecord)
-m2m_changed.connect(document_attached_changed,
- sender=ContextRecord.documents.through)
+m2m_changed.connect(document_attached_changed, sender=ContextRecord.documents.through)
for attr in ContextRecord.HISTORICAL_M2M:
- m2m_changed.connect(m2m_historization_changed,
- sender=getattr(ContextRecord, attr).through)
+ m2m_changed.connect(
+ m2m_historization_changed, sender=getattr(ContextRecord, attr).through
+ )
class RelationType(GeneralRelationType):
class Meta:
verbose_name = _("Relation type")
verbose_name_plural = _("Relation types")
- ordering = ('order', 'label')
+ ordering = ("order", "label")
class RecordRelationsManager(models.Manager):
def get_by_natural_key(self, left_record, right_record, relation_type):
- return self.get(left_record__uuid=left_record,
- right_record__uuid=right_record,
- relation_type__txt_idx=relation_type)
+ return self.get(
+ left_record__uuid=left_record,
+ right_record__uuid=right_record,
+ relation_type__txt_idx=relation_type,
+ )
class RecordRelations(GeneralRecordRelations, models.Model):
- MAIN_ATTR = 'left_record'
- left_record = models.ForeignKey(ContextRecord,
- related_name='right_relations')
- right_record = models.ForeignKey(ContextRecord,
- related_name='left_relations')
+ MAIN_ATTR = "left_record"
+ left_record = models.ForeignKey(ContextRecord, related_name="right_relations")
+ right_record = models.ForeignKey(ContextRecord, related_name="left_relations")
relation_type = models.ForeignKey(RelationType)
objects = RecordRelationsManager()
TABLE_COLS = [
- "left_record__label", "left_record__unit", "left_record__parcel",
+ "left_record__label",
+ "left_record__unit",
+ "left_record__parcel",
"relation_type",
- "right_record__label", "right_record__unit", "right_record__parcel",
+ "right_record__label",
+ "right_record__unit",
+ "right_record__parcel",
]
COL_LABELS = {
"left_record__label": _("ID (left)"),
@@ -1021,13 +1196,11 @@ class RecordRelations(GeneralRecordRelations, models.Model):
"right_record__unit": _("Context record type (right)"),
"right_record__parcel": _("Parcel (right)"),
"right_record__description": _("Description (right)"),
- "right_record__datings__period": _("Periods (right)")
+ "right_record__datings__period": _("Periods (right)"),
}
# search parameters
- EXTRA_REQUEST_KEYS = {
- "left_record__operation": "left_record__operation__pk"
- }
+ EXTRA_REQUEST_KEYS = {"left_record__operation": "left_record__operation__pk"}
class Meta:
verbose_name = _("Record relation")
@@ -1037,8 +1210,7 @@ class RecordRelations(GeneralRecordRelations, models.Model):
]
def natural_key(self):
- return self.left_record.uuid, self.right_record.uuid, \
- self.relation_type.txt_idx
+ return self.left_record.uuid, self.right_record.uuid, self.relation_type.txt_idx
post_delete.connect(post_delete_record_relation, sender=RecordRelations)
@@ -1062,34 +1234,40 @@ class RecordRelationView(models.Model):
"""
TABLE_COLS = [
"relation_type",
- "right_record__label", "right_record__unit",
+ "right_record__label",
+ "right_record__unit",
"right_record__parcel",
- "right_record__datings__period", "right_record__description"]
+ "right_record__datings__period",
+ "right_record__description",
+ ]
COL_LABELS = {
"relation_type": _("Relation type"),
"right_record__label": _("ID"),
"right_record__unit": _("Context record type"),
"right_record__parcel": _("Parcel"),
"right_record__description": _("Description"),
- "right_record__datings__period": _("Periods")
+ "right_record__datings__period": _("Periods"),
}
# search parameters
EXTRA_REQUEST_KEYS = {
"left_record_id": "left_record_id",
- "right_record__unit": "right_record__unit__label"
+ "right_record__unit": "right_record__unit__label",
}
- left_record = models.ForeignKey(ContextRecord, related_name='+',
- on_delete=models.DO_NOTHING)
- right_record = models.ForeignKey(ContextRecord, related_name='+',
- on_delete=models.DO_NOTHING)
- relation_type = models.ForeignKey(RelationType, related_name='+',
- on_delete=models.DO_NOTHING)
+ left_record = models.ForeignKey(
+ ContextRecord, related_name="+", on_delete=models.DO_NOTHING
+ )
+ right_record = models.ForeignKey(
+ ContextRecord, related_name="+", on_delete=models.DO_NOTHING
+ )
+ relation_type = models.ForeignKey(
+ RelationType, related_name="+", on_delete=models.DO_NOTHING
+ )
class Meta:
managed = False
- db_table = 'record_relations'
- unique_together = ('id', 'right_record')
+ db_table = "record_relations"
+ unique_together = ("id", "right_record")
permissions = [
("view_recordrelation", "Can view all record relations - view"),
]
@@ -1099,7 +1277,7 @@ class RecordRelationView(models.Model):
return []
def __str__(self):
- return "{} \"{}\"".format(self.relation_type, self.right_record)
+ return '{} "{}"'.format(self.relation_type, self.right_record)
class ContextRecordTree(models.Model):
@@ -1178,13 +1356,14 @@ class ContextRecordTree(models.Model):
cr = models.ForeignKey(
"archaeological_context_records.ContextRecord",
verbose_name=_("Context record"),
- related_name="context_record_tree_parent")
+ related_name="context_record_tree_parent",
+ )
cr_parent = models.ForeignKey(
"archaeological_context_records.ContextRecord",
verbose_name=_("Context record parent"),
- related_name="context_record_tree_child")
+ related_name="context_record_tree_child",
+ )
class Meta:
managed = False
- db_table = 'context_records_tree'
-
+ db_table = "context_records_tree"