summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CHANGES.md16
-rw-r--r--archaeological_context_records/models.py10
-rw-r--r--archaeological_files/forms.py55
-rw-r--r--archaeological_files/models.py5
-rw-r--r--archaeological_files/tests.py14
-rw-r--r--archaeological_files_pdl/forms.py66
-rw-r--r--archaeological_finds/models.py4
-rw-r--r--archaeological_operations/forms.py57
-rw-r--r--example_project/local_settings.py.gitlab-ci1
-rw-r--r--example_project/settings.py37
-rw-r--r--ishtar_common/admin.py4
-rw-r--r--ishtar_common/forms.py23
-rw-r--r--ishtar_common/migrations/0064_auto__add_field_importercolumn_label.py465
-rw-r--r--ishtar_common/models.py54
-rw-r--r--ishtar_common/templates/blocks/JQueryJqGrid.html2
-rw-r--r--ishtar_common/templates/ishtar/blocks/window_tables/dynamic_documents.html2
-rw-r--r--ishtar_common/views.py38
-rw-r--r--ishtar_common/widgets.py25
-rw-r--r--ishtar_common/wizards.py4
-rw-r--r--version.py2
21 files changed, 757 insertions, 128 deletions
diff --git a/.gitignore b/.gitignore
index 947a0dfef..484d2af20 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@ oook_replace
.cache
dist
ishtar.egg-info
+.idea
diff --git a/CHANGES.md b/CHANGES.md
index 58e3d6f36..9f671d7b4 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,22 @@
Ishtar changelog
================
+0.98.10 (2016-11-03)
+--------------------
+
+### Features ###
+
+- Force regeneration of cached labels when add M2M or changing ids
+- Use lazy model evaluation for fixed type constraints
+- Imports: add label to column definitions
+- Use spatialite for tests
+- Change default logging conf
+
+### Bug fixes ###
+
+- JQueryJqGrid: by default sorting is made using ordering in meta (fixes serious
+ performance issues)
+
0.98.9 (2016-10-23)
-------------------
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py
index bbfb410f8..3f4dc1598 100644
--- a/archaeological_context_records/models.py
+++ b/archaeological_context_records/models.py
@@ -121,13 +121,13 @@ post_delete.connect(post_save_cache, sender=IdentificationType)
class ContextRecord(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem):
SHOW_URL = 'show-contextrecord'
SLUG = 'contextrecord'
- TABLE_COLS = ['parcel.town', 'operation.year',
- 'operation.operation_code',
+ TABLE_COLS = ['parcel__town', 'operation__year',
+ 'operation__operation_code',
'label', 'unit']
if settings.COUNTRY == 'fr':
- TABLE_COLS.insert(1, 'operation.code_patriarche')
+ TABLE_COLS.insert(1, 'operation__code_patriarche')
TABLE_COLS_FOR_OPE = ['label', 'parcel', 'unit',
- 'datings.period', 'description']
+ 'datings__period', 'description']
TABLE_COLS_FOR_OPE_LBL = {'section__parcel_number': _("Parcel")}
CONTEXTUAL_TABLE_COLS = {
'full': {
@@ -140,6 +140,7 @@ class ContextRecord(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem):
EXTRA_REQUEST_KEYS = {
'parcel__town': 'parcel__town__pk',
'operation__year': 'operation__year__contains',
+ 'year': 'operation__year__contains',
'operation__code_patriarche': 'operation__code_patriarche',
'operation__operation_code': 'operation__operation_code',
'datings__period': 'datings__period__pk',
@@ -363,6 +364,7 @@ class ContextRecord(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem):
self.auto_external_id = True
self.external_id = external_id
if updated:
+ self._cached_label_checked = False
self.save()
return returned
diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py
index 26b839940..42a645171 100644
--- a/archaeological_files/forms.py
+++ b/archaeological_files/forms.py
@@ -28,8 +28,9 @@ from django.core import validators
from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe
-from ishtar_common.models import Person, PersonType, Organization, \
- OrganizationType, valid_id, Department
+from ishtar_common.models import Person, Organization, \
+ valid_id, Department, person_type_pks_lazy, \
+ person_type_pk_lazy, organization_type_pks_lazy
from archaeological_operations.models import ActType, AdministrativeAct, \
OperationType
import models
@@ -38,15 +39,9 @@ from ishtar_common.forms import FinalForm, get_now, reverse_lazy, TableSelect, \
from ishtar_common.forms_common import get_town_field
from archaeological_operations.forms import AdministrativeActOpeForm, \
AdministrativeActOpeFormSelection, \
- ParcelField, SLICING, HEAD_SCIENTIST, SRA_AGENT, AdministrativeActModifForm
+ ParcelField, SLICING, AdministrativeActModifForm
from ishtar_common import widgets
-GENERAL_CONTRACTOR, created = PersonType.objects.get_or_create(
- txt_idx='general_contractor')
-
-GENERAL_CONTRACTOR_ORGA, created = OrganizationType.objects.get_or_create(
- txt_idx='general_contractor')
-
class FileSelect(TableSelect):
year = forms.IntegerField(label=_("Year"))
@@ -70,21 +65,22 @@ class FileSelect(TableSelect):
label=_(u"In charge"),
widget=widgets.JQueryAutoComplete(
reverse_lazy('autocomplete-person',
- args=[SRA_AGENT.pk]),
+ args=[person_type_pk_lazy('sra_agent')]),
associated_model=Person),
validators=[valid_id(Person)])
general_contractor = forms.IntegerField(
label=_(u"General contractor"),
widget=widgets.JQueryAutoComplete(
reverse_lazy('autocomplete-person',
- args=[GENERAL_CONTRACTOR.pk]),
+ args=[person_type_pk_lazy('general_contractor')]),
associated_model=Person),
validators=[valid_id(Person)])
general_contractor__attached_to = forms.IntegerField(
label=_(u"Organization of general contractor"),
widget=widgets.JQueryAutoComplete(
reverse_lazy('autocomplete-organization',
- args=[GENERAL_CONTRACTOR_ORGA.pk]),
+ args=[organization_type_pks_lazy([
+ 'general_contractor'])]),
associated_model=Organization),
validators=[valid_id(Organization)])
history_creator = forms.IntegerField(
@@ -205,8 +201,10 @@ class FileFormGeneral(ManageOldType, forms.Form):
in_charge = forms.IntegerField(
label=_("Person in charge"),
widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person', args=[SRA_AGENT.pk]),
- limit={'person_types': [SRA_AGENT.pk]},
+ reverse_lazy('autocomplete-person', args=[
+ person_type_pks_lazy(['sra_agent'])]),
+ limit={'person_types': [
+ person_type_pk_lazy('sra_agent')]},
associated_model=Person, new=True),
validators=[valid_id(Person)])
year = forms.IntegerField(label=_("Year"),
@@ -272,12 +270,6 @@ class FileFormGeneralRO(FileFormGeneral):
_(u"Another file with this numeric id exists."))
return cleaned_data
-RESPONSIBLE_PLANNING_SERVICE, created = PersonType.objects.get_or_create(
- txt_idx='responsible_planning_service')
-
-RESPONSIBLE_PLANNING_SERVICE_ORGA, created = \
- OrganizationType.objects.get_or_create(txt_idx='planning_service')
-
class FileFormPreventive(ManageOldType, forms.Form):
form_label = _(u"Preventive informations")
@@ -290,10 +282,10 @@ class FileFormPreventive(ManageOldType, forms.Form):
widget=widgets.JQueryAutoComplete(
reverse_lazy(
'autocomplete-person',
- args=[PersonType.objects.get(txt_idx='general_contractor').pk]
+ args=[person_type_pks_lazy(['general_contractor'])]
),
limit={'person_types': [
- PersonType.objects.get(txt_idx='general_contractor').pk]},
+ person_type_pk_lazy('general_contractor')]},
associated_model=Person, new=True),
validators=[valid_id(Person)])
responsible_town_planning_service = forms.IntegerField(
@@ -302,10 +294,11 @@ class FileFormPreventive(ManageOldType, forms.Form):
widget=widgets.JQueryAutoComplete(
reverse_lazy(
'autocomplete-person',
- args=[RESPONSIBLE_PLANNING_SERVICE.pk]
+ args=[person_type_pks_lazy(['responsible_planning_service'])]
),
limit={'person_types': [
- RESPONSIBLE_PLANNING_SERVICE.pk]},
+ person_type_pk_lazy('responsible_planning_service')
+ ]},
associated_model=Person, new=True),
validators=[valid_id(Person)])
permit_type = forms.ChoiceField(label=_(u"Permit type"), required=False,
@@ -351,10 +344,9 @@ class FileFormResearch(ManageOldType, forms.Form):
widget=widgets.JQueryAutoComplete(
reverse_lazy(
'autocomplete-person',
- args=["_".join([unicode(HEAD_SCIENTIST.pk),
- unicode(SRA_AGENT.pk)])]),
- limit={'person_types': [unicode(HEAD_SCIENTIST.pk),
- unicode(SRA_AGENT.pk)]},
+ args=[person_type_pks_lazy(['head_scientist', 'sra_agent'])]),
+ limit={'person_types': [person_type_pk_lazy('head_scientist'),
+ person_type_pk_lazy('sra_agent')]},
associated_model=Person, new=True),
label=_(u"Scientist in charge"))
requested_operation_type = forms.ChoiceField(
@@ -454,8 +446,7 @@ class AdministrativeActFileSelect(TableSelect):
widget=widgets.JQueryAutoComplete(
reverse_lazy(
'autocomplete-person',
- args=[
- PersonType.objects.get(txt_idx='general_contractor').pk]),
+ args=[person_type_pk_lazy('general_contractor')]),
associated_model=Person),
validators=[valid_id(Person)])
associated_file__general_contractor__attached_to = forms.IntegerField(
@@ -463,7 +454,7 @@ class AdministrativeActFileSelect(TableSelect):
widget=widgets.JQueryAutoComplete(
reverse_lazy(
'autocomplete-organization',
- args=[GENERAL_CONTRACTOR_ORGA.pk]),
+ args=[organization_type_pks_lazy(['general_contractor'])]),
associated_model=Organization),
validators=[valid_id(Organization)])
associated_file__numeric_reference = forms.IntegerField(
@@ -476,7 +467,7 @@ class AdministrativeActFileSelect(TableSelect):
widget=widgets.JQueryAutoComplete(
reverse_lazy(
'autocomplete-person',
- args=[SRA_AGENT.pk]),
+ args=[person_type_pk_lazy('sra_agent')]),
associated_model=Person),
validators=[valid_id(Person)])
associated_file__permit_reference = forms.CharField(
diff --git a/archaeological_files/models.py b/archaeological_files/models.py
index 623eb1dee..1d8317b31 100644
--- a/archaeological_files/models.py
+++ b/archaeological_files/models.py
@@ -521,6 +521,7 @@ class File(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,
self.auto_external_id = True
self.external_id = external_id
if updated:
+ self._cached_label_checked = False
self.save()
return returned
@@ -536,9 +537,9 @@ post_save.connect(cached_label_changed, sender=File)
class FileByDepartment(models.Model):
- '''
+ """
Database view for dashboard
- '''
+ """
file = models.ForeignKey(File, verbose_name=_(u"File"))
department = models.ForeignKey(Department, verbose_name=_(u"Department"),
blank=True, null=True)
diff --git a/archaeological_files/tests.py b/archaeological_files/tests.py
index dfaa1fb09..4a09e1caa 100644
--- a/archaeological_files/tests.py
+++ b/archaeological_files/tests.py
@@ -86,6 +86,20 @@ class FileTest(TestCase, FileInit):
u"{}-{}".format(self.item.year,
self.item.numeric_reference))
+ def testCachedLabel(self):
+ lbls = ['No town', self.item.external_id,
+ self.item.internal_reference]
+ lbl = settings.JOINT.join(lbls)
+ self.assertEqual(self.item.cached_label, lbl)
+ default_town = Town.objects.create(name="Paris", numero_insee='75001')
+ self.item.towns.add(default_town)
+ # manually done inside wizards
+ self.item._cached_label_checked = False
+ self.item.save()
+ lbls[0] = "Paris"
+ lbl = settings.JOINT.join(lbls)
+ self.assertEqual(self.item.cached_label, lbl)
+
def testAddAndGetHistorized(self):
"""
Test correct new version and correct access to history
diff --git a/archaeological_files_pdl/forms.py b/archaeological_files_pdl/forms.py
index 99dc97137..cf241aa18 100644
--- a/archaeological_files_pdl/forms.py
+++ b/archaeological_files_pdl/forms.py
@@ -24,15 +24,12 @@ from django.core import validators
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
-from ishtar_common.models import Person, Town, Department, valid_id
+from ishtar_common.models import Person, Town, Department, valid_id, \
+ person_type_pk_lazy, person_type_pks_lazy, organization_type_pks_lazy, \
+ organization_type_pk_lazy
from archaeological_files import models
from ishtar_common.forms import get_now, reverse_lazy, ManageOldType
-from archaeological_files.forms import GENERAL_CONTRACTOR, \
- GENERAL_CONTRACTOR_ORGA, RESPONSIBLE_PLANNING_SERVICE, \
- RESPONSIBLE_PLANNING_SERVICE_ORGA
-
-from archaeological_operations.forms import SRA_AGENT
from ishtar_common import widgets
@@ -135,10 +132,10 @@ class FileFormResearchAddress(forms.Form):
class PersonOrgaForm(forms.Form):
PERSON_FIELD = 'TO BE DEFINED'
- PERSON_TYPE = GENERAL_CONTRACTOR
+ PERSON_TYPE_PK = person_type_pk_lazy('general_contractor')
PERSON_LABEL = ""
ORGA_FIELD = 'TO BE DEFINED'
- ORGA_TYPE = GENERAL_CONTRACTOR_ORGA
+ ORGA_TYPE_PK = organization_type_pk_lazy('general_contractor')
ORGA_LABEL = ""
def _media(self):
@@ -205,10 +202,10 @@ class PersonOrgaForm(forms.Form):
initial=initial.get(self.PERSON_FIELD, None),
widget=widgets.JQueryPersonOrganization(
reverse_lazy('autocomplete-person',
- args=[self.PERSON_TYPE.pk]),
+ args=[self.PERSON_TYPE_PK]),
reverse_lazy('person_create'),
model=Person,
- limit={'person_types': [self.PERSON_TYPE.pk],
+ limit={'person_types': [self.PERSON_TYPE_PK],
'attached_to__isnull': True},
js_template='ishtar/blocks/JQueryNaturalPerson.js',
new=True),
@@ -220,10 +217,10 @@ class PersonOrgaForm(forms.Form):
initial=initial.get(self.ORGA_FIELD, None),
widget=widgets.JQueryPersonOrganization(
reverse_lazy('autocomplete-organization',
- args=[self.ORGA_TYPE.pk]),
+ args=[self.ORGA_TYPE_PK]),
reverse_lazy('organization_create'),
model=models.Organization,
- limit={'organization_type': [self.ORGA_TYPE.pk]},
+ limit={'organization_type': [self.ORGA_TYPE_PK]},
js_template='ishtar/blocks/JQueryCorporationPerson.js',
new=True),
validators=[valid_id(models.Organization)])
@@ -238,12 +235,15 @@ class FileFormGeneralContractor(PersonOrgaForm):
required=False,
widget=widgets.JQueryPersonOrganization(
reverse_lazy('autocomplete-organization',
- args=[GENERAL_CONTRACTOR_ORGA.pk]),
+ args=[
+ organization_type_pks_lazy(['general_contractor'])]
+ ),
reverse_lazy('organization_create'),
model=models.Organization,
limit={
- 'organization_type': [GENERAL_CONTRACTOR_ORGA.pk]
- },
+ 'organization_type': [
+ organization_type_pk_lazy('general_contractor')
+ ]},
js_template='ishtar/blocks/JQueryCorporationPerson.js',
new=True),
validators=[valid_id(models.Organization)]
@@ -253,9 +253,13 @@ class FileFormGeneralContractor(PersonOrgaForm):
required=False,
widget=widgets.JQueryAutoComplete(
reverse_lazy('autocomplete-person',
- args=[GENERAL_CONTRACTOR.pk]),
+ args=[
+ person_type_pks_lazy(['general_contractor'])
+ ]),
associated_model=Person,
- limit={'person_types': [GENERAL_CONTRACTOR.pk]},
+ limit={'person_types': [
+ person_type_pk_lazy(['general_contractor'])
+ ]},
dynamic_limit=['general_contractor'],
url_new='new-person-noorga',
new=True),
@@ -263,10 +267,10 @@ class FileFormGeneralContractor(PersonOrgaForm):
)
PERSON_FIELD = 'general_contractor'
- PERSON_TYPE = GENERAL_CONTRACTOR
+ PERSON_TYPE_PK = person_type_pk_lazy('general_contractor')
PERSON_LABEL = _(u"General contractor")
ORGA_FIELD = 'corporation_general_contractor'
- ORGA_TYPE = GENERAL_CONTRACTOR_ORGA
+ ORGA_TYPE_PK = organization_type_pk_lazy('general_contractor')
ORGA_LABEL = _(u"General contractor")
def __init__(self, *args, **kwargs):
@@ -327,10 +331,10 @@ class FileFormGeneralContractor(PersonOrgaForm):
initial=initial.get(self.PERSON_FIELD, None),
widget=widgets.JQueryPersonOrganization(
reverse_lazy('autocomplete-person',
- args=[self.PERSON_TYPE.pk]),
+ args=[self.PERSON_TYPE_PK]),
reverse_lazy('person_create'),
model=Person,
- limit={'person_types': [self.PERSON_TYPE.pk],
+ limit={'person_types': [self.PERSON_TYPE_PK],
'attached_to__isnull': True},
js_template='ishtar/blocks/JQueryNaturalPerson.js',
new=True),
@@ -349,12 +353,14 @@ class FileFormPlanningService(forms.Form):
label=_("Planning service"),
required=False,
widget=widgets.JQueryPersonOrganization(
- reverse_lazy('autocomplete-organization',
- args=[RESPONSIBLE_PLANNING_SERVICE_ORGA.pk]),
+ reverse_lazy(
+ 'autocomplete-organization',
+ args=[organization_type_pks_lazy(['planning_service'])]),
reverse_lazy('organization_create'),
model=models.Organization,
limit={
- 'organization_type': [RESPONSIBLE_PLANNING_SERVICE_ORGA.pk]
+ 'organization_type':
+ [organization_type_pk_lazy(['planning_service'])],
},
js_template='ishtar/blocks/JQueryCorporationPerson.js',
new=True),
@@ -365,9 +371,13 @@ class FileFormPlanningService(forms.Form):
required=False,
widget=widgets.JQueryAutoComplete(
reverse_lazy('autocomplete-person',
- args=[RESPONSIBLE_PLANNING_SERVICE.pk]),
+ args=[
+ person_type_pks_lazy(
+ ['responsible_planning_service'])]),
associated_model=Person,
- limit={'person_types': [RESPONSIBLE_PLANNING_SERVICE.pk]},
+ limit={'person_types': [
+ person_type_pk_lazy('responsible_planning_service')
+ ]},
dynamic_limit=['planning_service'],
url_new='new-person-noorga',
new=True),
@@ -384,10 +394,10 @@ class FileFormInstruction(forms.Form):
widget=widgets.JQueryAutoComplete(
reverse_lazy(
'autocomplete-person',
- args=[SRA_AGENT.pk]),
+ args=[person_type_pks_lazy(["sra_agent"])]),
limit={
'person_types': [
- SRA_AGENT.pk]
+ person_type_pk_lazy('sra_agent')]
},
associated_model=Person, new=True),
validators=[valid_id(Person)])
diff --git a/archaeological_finds/models.py b/archaeological_finds/models.py
index 5799d0e9a..aa5eacc30 100644
--- a/archaeological_finds/models.py
+++ b/archaeological_finds/models.py
@@ -269,6 +269,7 @@ class BaseFind(BaseHistorizedItem, OwnPerms):
self.auto_external_id = True
self.external_id = external_id
if updated:
+ self._cached_label_checked = False
self.save()
return returned
@@ -653,6 +654,7 @@ class Find(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem):
self.auto_external_id = True
self.external_id = external_id
if updated:
+ self._cached_label_checked = False
self.save()
return
@@ -671,6 +673,7 @@ class Find(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem):
self.index = q.aggregate(Max('index'))['index__max'] + 1
else:
self.index = 1
+ self._cached_label_checked = False
self.save()
for base_find in self.base_finds.filter(
context_record__operation__pk__isnull=False).all():
@@ -689,6 +692,7 @@ class Find(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem):
modified = True
if modified:
base_find.skip_history_when_saving = True
+ base_find._cached_label_checked = False
base_find.save()
# if not base_find.material_index:
# idx = BaseFind.objects\
diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py
index a12f245cb..37c35f4be 100644
--- a/archaeological_operations/forms.py
+++ b/archaeological_operations/forms.py
@@ -34,7 +34,9 @@ from django.utils.translation import ugettext_lazy as _, pgettext_lazy
from django.utils.safestring import mark_safe
from ishtar_common.models import valid_id, PersonType, Person, Town, \
- DocumentTemplate, Organization, OrganizationType, get_current_profile
+ DocumentTemplate, Organization, OrganizationType, get_current_profile, \
+ person_type_pks_lazy, person_type_pk_lazy, organization_type_pks_lazy, \
+ organization_type_pk_lazy
from ishtar_common.wizards import MultiValueDict
@@ -448,12 +450,6 @@ class RecordRelationsForm(ManageOldType, forms.Form):
RecordRelationsFormSet = formset_factory(RecordRelationsForm, can_delete=True)
RecordRelationsFormSet.form_label = _(u"Relations")
-SRA_AGENT, created = PersonType.objects.get_or_create(txt_idx='sra_agent')
-HEAD_SCIENTIST, created = PersonType.objects.get_or_create(
- txt_idx='head_scientist')
-
-OPERATOR, created = OrganizationType.objects.get_or_create(txt_idx='operator')
-
class OperationSelect(TableSelect):
year = forms.IntegerField(label=_("Year"))
@@ -476,22 +472,23 @@ class OperationSelect(TableSelect):
widget=widgets.JQueryAutoComplete(
reverse_lazy(
'autocomplete-person-permissive',
- args=["_".join(
- [unicode(PersonType.objects.get(txt_idx='sra_agent').pk)])]
+ args=[person_type_pks_lazy(['sra_agent'])]
),
associated_model=Person),
label=_(u"In charge"))
scientist = forms.IntegerField(
widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person-permissive',
- args=["_".join([unicode(HEAD_SCIENTIST.pk),
- unicode(SRA_AGENT.pk)])]),
+ reverse_lazy(
+ 'autocomplete-person-permissive',
+ args=[person_type_pks_lazy(['sra_agent', 'head_scientist'])]),
associated_model=Person),
label=_(u"Scientist in charge"))
operator = forms.IntegerField(
label=_("Operator"),
widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-organization', args=[OPERATOR.pk]),
+ reverse_lazy(
+ 'autocomplete-organization',
+ args=[organization_type_pks_lazy(['operator'])]),
associated_model=Organization),
validators=[valid_id(Organization)])
# operator_reference = forms.CharField(label=_(u"Operator reference"),
@@ -762,18 +759,21 @@ class OperationFormGeneral(ManageOldType, forms.Form):
scientist = forms.IntegerField(
label=_("Head scientist"),
widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person',
- args=["_".join([unicode(HEAD_SCIENTIST.pk),
- unicode(SRA_AGENT.pk)])]),
+ reverse_lazy(
+ 'autocomplete-person',
+ args=[person_type_pks_lazy(['head_scientist', 'sra_agent'])]),
associated_model=Person,
- limit={'person_types': (HEAD_SCIENTIST.pk, SRA_AGENT.pk)},
+ limit={
+ 'person_types': (person_type_pk_lazy('head_scientist'),
+ person_type_pk_lazy('sra_agent'))},
new=True),
validators=[valid_id(Person)], required=False)
operator = forms.IntegerField(
label=_("Operator"),
widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-organization', args=[OPERATOR.pk]),
- limit={'organization_type': (OPERATOR.pk,)},
+ reverse_lazy('autocomplete-organization',
+ args=[organization_type_pk_lazy('operator')]),
+ limit={'organization_type': organization_type_pk_lazy('operator')},
associated_model=Organization, new=True),
validators=[valid_id(Organization)], required=False)
operator_reference = forms.CharField(label=_(u"Operator reference"),
@@ -781,10 +781,12 @@ class OperationFormGeneral(ManageOldType, forms.Form):
in_charge = forms.IntegerField(
label=_("In charge"),
widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person',
- args=["_".join([unicode(SRA_AGENT.pk)])]),
+ reverse_lazy(
+ 'autocomplete-person',
+ args=[person_type_pks_lazy(['sra_agent'])]),
associated_model=Person,
- limit={'person_types': [SRA_AGENT.pk]}, new=True),
+ limit={'person_types': [person_type_pk_lazy('sra_agent')]},
+ new=True),
validators=[valid_id(Person)], required=False)
surface = forms.IntegerField(
required=False, widget=widgets.AreaWidget,
@@ -812,10 +814,13 @@ class OperationFormGeneral(ManageOldType, forms.Form):
cira_rapporteur = forms.IntegerField(
label=u"Rapporteur CIRA",
widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person',
- args=["_".join([unicode(HEAD_SCIENTIST.pk),
- unicode(SRA_AGENT.pk)])]),
- limit={'person_types': [SRA_AGENT.pk, HEAD_SCIENTIST.pk]},
+ reverse_lazy(
+ 'autocomplete-person',
+ args=[person_type_pks_lazy(['head_scientist',
+ 'sra_agent'])]),
+ limit={'person_types': [
+ person_type_pk_lazy('sra_agent'),
+ person_type_pk_lazy('head_scientist')]},
associated_model=Person, new=True),
validators=[valid_id(Person)], required=False)
documentation_deadline = forms.DateField(
diff --git a/example_project/local_settings.py.gitlab-ci b/example_project/local_settings.py.gitlab-ci
index 7f4bcefa1..81196b4a0 100644
--- a/example_project/local_settings.py.gitlab-ci
+++ b/example_project/local_settings.py.gitlab-ci
@@ -12,3 +12,4 @@ DATABASES = {
LOGFILE = '/tmp/ishtar.log'
PROJECT_SLUG = "CI-instance"
+USE_SPATIALITE_FOR_TESTS = False
diff --git a/example_project/settings.py b/example_project/settings.py
index 128befe5a..a191b83b3 100644
--- a/example_project/settings.py
+++ b/example_project/settings.py
@@ -10,6 +10,7 @@ DEBUG_TOOLBAR = False
TEMPLATE_DEBUG = DEBUG
SQL_DEBUG = False
DJANGO_EXTENSIONS = False
+USE_SPATIALITE_FOR_TESTS = True
if "test" in sys.argv:
sys.path.insert(0, '..')
@@ -155,6 +156,12 @@ INSTALLED_APPS = [
LOGFILE = ''
+default_handler = {
+ 'handlers': ['logfile'],
+ 'level': 'INFO',
+ 'propogate': False
+}
+
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
@@ -178,24 +185,24 @@ LOGGING = {
},
},
'loggers': {
- # Again, default Django configuration to email unhandled exceptions
'django.request': {
- 'handlers': ['mail_admins'],
+ 'handlers': ['mail_admins', 'logfile'],
'level': 'ERROR',
'propagate': True,
},
- # Might as well log any errors anywhere else in Django
'django': {
'handlers': ['logfile'],
'level': 'ERROR',
'propagate': False,
},
- # Your own app - this assumes all your logger names start with "myapp."
- 'chimere': {
- 'handlers': ['logfile'],
- 'level': 'WARNING', # Or maybe INFO or DEBUG
- 'propogate': False
- },
+ 'ishtar_pdl': default_handler,
+ 'ishtar_common': default_handler,
+ 'archaeological_files_pdl': default_handler,
+ 'archaeological_files': default_handler,
+ 'archaeological_operations': default_handler,
+ 'archaeological_context_records': default_handler,
+ 'archaeological_warehouse': default_handler,
+ 'archaeological_finds': default_handler,
},
}
@@ -230,6 +237,10 @@ except ImportError, e:
if 'test' in sys.argv:
SOUTH_TESTS_MIGRATE = False
+ if USE_SPATIALITE_FOR_TESTS:
+ DATABASES['default']['ENGINE'] = \
+ 'django.contrib.gis.db.backends.spatialite'
+
PROJECT_SLUG = locals().get('PROJECT_SLUG', 'default')
if LOGFILE:
@@ -243,6 +254,11 @@ INTERNAL_IPS = ('127.0.0.1',)
JQUERY_URL = STATIC_URL + "js/jquery.min.js"
JQUERY_UI_URL = STATIC_URL + "js/jquery-ui/"
+if DEBUG:
+ # make all loggers use the console
+ for logger in LOGGING['loggers']:
+ LOGGING['loggers'][logger]['handlers'] += ['console']
+
if DJANGO_EXTENSIONS:
INSTALLED_APPS.append('django_extensions')
@@ -272,3 +288,6 @@ if SQL_DEBUG:
'level': 'DEBUG',
'handlers': ['console'],
}
+
+if 'test' in sys.argv:
+ PROJECT_SLUG += "-test"
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py
index fb0ab1170..aa04a7b1c 100644
--- a/ishtar_common/admin.py
+++ b/ishtar_common/admin.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2015 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2010-2016 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -202,7 +202,7 @@ class ImportTargetInline(admin.TabularInline):
class ImporterColumnAdmin(admin.ModelAdmin):
- list_display = ('importer_type', 'col_number', 'description',
+ list_display = ('label', 'importer_type', 'col_number', 'description',
'targets_lbl', 'duplicate_fields_lbl', 'required')
list_filter = ('importer_type',)
inlines = (ImporterDuplicateFieldInline, ImportTargetInline)
diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py
index b0e8cb43c..043b03f61 100644
--- a/ishtar_common/forms.py
+++ b/ishtar_common/forms.py
@@ -31,6 +31,10 @@ from django.utils import formats
from django.utils.functional import lazy
from django.utils.translation import ugettext_lazy as _
+import models
+import widgets
+
+
# from formwizard.forms import NamedUrlSessionFormWizard
@@ -44,10 +48,23 @@ class NamedUrlSessionFormWizard(forms.Form):
def rindex(self, idx):
return self.url_name.rindex(idx)
-import models
-import widgets
-reverse_lazy = lazy(reverse, unicode)
+def my_reverse(*args, **kwargs):
+ """
+ Custom reverse method in order to evaluate lazy args
+ """
+ if 'args' in kwargs:
+ my_args = []
+ for arg in kwargs['args']:
+ if callable(arg):
+ my_args.append(unicode(arg()))
+ else:
+ my_args.append(unicode(arg))
+ kwargs['args'] = my_args
+ return reverse(*args, **kwargs)
+
+
+reverse_lazy = lazy(my_reverse, unicode)
regexp_name = re.compile(r"^[,:/\w\-'\"() \&\[\]@]+$", re.UNICODE)
name_validator = validators.RegexValidator(
diff --git a/ishtar_common/migrations/0064_auto__add_field_importercolumn_label.py b/ishtar_common/migrations/0064_auto__add_field_importercolumn_label.py
new file mode 100644
index 000000000..2f2b6efcc
--- /dev/null
+++ b/ishtar_common/migrations/0064_auto__add_field_importercolumn_label.py
@@ -0,0 +1,465 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding field 'ImporterColumn.label'
+ db.add_column('ishtar_common_importercolumn', 'label',
+ self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'ImporterColumn.label'
+ db.delete_column('ishtar_common_importercolumn', 'label')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'ishtar_common.arrondissement': {
+ 'Meta': {'object_name': 'Arrondissement'},
+ 'department': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Department']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '30'})
+ },
+ 'ishtar_common.author': {
+ 'Meta': {'object_name': 'Author'},
+ 'author_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.AuthorType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'author'", 'to': "orm['ishtar_common.Person']"})
+ },
+ 'ishtar_common.authortype': {
+ 'Meta': {'object_name': 'AuthorType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.canton': {
+ 'Meta': {'object_name': 'Canton'},
+ 'arrondissement': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Arrondissement']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '30'})
+ },
+ 'ishtar_common.department': {
+ 'Meta': {'ordering': "['number']", 'object_name': 'Department'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
+ 'number': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '3'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.State']", 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.documenttemplate': {
+ 'Meta': {'ordering': "['associated_object_name', 'name']", 'object_name': 'DocumentTemplate'},
+ 'associated_object_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'template': ('django.db.models.fields.files.FileField', [], {'max_length': '100'})
+ },
+ 'ishtar_common.format': {
+ 'Meta': {'object_name': 'Format'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.formatertype': {
+ 'Meta': {'ordering': "('formater_type', 'options')", 'unique_together': "(('formater_type', 'options', 'many_split'),)", 'object_name': 'FormaterType'},
+ 'formater_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'many_split': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'options': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.globalvar': {
+ 'Meta': {'ordering': "['slug']", 'object_name': 'GlobalVar'},
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.historicalorganization': {
+ 'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalOrganization'},
+ 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}),
+ 'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'history_creator_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'history_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'history_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'history_modifier_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'history_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'history_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
+ 'merge_key': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'organization_type_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.historicalperson': {
+ 'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalPerson'},
+ 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}),
+ 'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
+ 'attached_to_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'contact_type': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'history_creator_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'history_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'history_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'history_modifier_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'history_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'history_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
+ 'merge_key': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'old_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'raw_name': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'salutation': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'surname': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'title_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.import': {
+ 'Meta': {'object_name': 'Import'},
+ 'conservative_import': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}),
+ 'encoding': ('django.db.models.fields.CharField', [], {'default': "'utf-8'", 'max_length': '15'}),
+ 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'error_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'imported_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+ 'imported_images': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.ImporterType']"}),
+ 'match_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'result_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'seconds_remaining': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'skip_lines': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'state': ('django.db.models.fields.CharField', [], {'default': "'C'", 'max_length': '2'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.IshtarUser']"})
+ },
+ 'ishtar_common.importercolumn': {
+ 'Meta': {'ordering': "('importer_type', 'col_number')", 'unique_together': "(('importer_type', 'col_number'),)", 'object_name': 'ImporterColumn'},
+ 'col_number': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'columns'", 'to': "orm['ishtar_common.ImporterType']"}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'regexp_pre_filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Regexp']", 'null': 'True', 'blank': 'True'}),
+ 'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'ishtar_common.importerdefault': {
+ 'Meta': {'object_name': 'ImporterDefault'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'defaults'", 'to': "orm['ishtar_common.ImporterType']"}),
+ 'target': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.importerdefaultvalues': {
+ 'Meta': {'object_name': 'ImporterDefaultValues'},
+ 'default_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'default_values'", 'to': "orm['ishtar_common.ImporterDefault']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'target': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'value': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.importerduplicatefield': {
+ 'Meta': {'object_name': 'ImporterDuplicateField'},
+ 'column': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'duplicate_fields'", 'to': "orm['ishtar_common.ImporterColumn']"}),
+ 'concat': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'concat_str': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}),
+ 'field_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'force_new': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ },
+ 'ishtar_common.importertype': {
+ 'Meta': {'object_name': 'ImporterType'},
+ 'associated_models': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_template': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+ 'unicity_keys': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
+ 'users': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['ishtar_common.IshtarUser']", 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.importtarget': {
+ 'Meta': {'object_name': 'ImportTarget'},
+ 'column': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'targets'", 'to': "orm['ishtar_common.ImporterColumn']"}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'concat': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'concat_str': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}),
+ 'force_new': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'formater_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.FormaterType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'regexp_filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Regexp']", 'null': 'True', 'blank': 'True'}),
+ 'target': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.ishtarsiteprofile': {
+ 'Meta': {'ordering': "['label']", 'object_name': 'IshtarSiteProfile'},
+ 'active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'base_find_external_id': ('django.db.models.fields.TextField', [], {'default': "'{context_record__external_id}-{label}'"}),
+ 'context_record': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'context_record_external_id': ('django.db.models.fields.TextField', [], {'default': "'{parcel__external_id}-{label}'"}),
+ 'currency': ('django.db.models.fields.CharField', [], {'default': "u'\\u20ac'", 'max_length': "'5'"}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'file_external_id': ('django.db.models.fields.TextField', [], {'default': "'{year}-{numeric_reference}'"}),
+ 'files': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'find': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'find_external_id': ('django.db.models.fields.TextField', [], {'default': "'{get_first_base_find__context_record__external_id}-{label}'"}),
+ 'homepage': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.TextField', [], {}),
+ 'parcel_external_id': ('django.db.models.fields.TextField', [], {'default': "'{associated_file__external_id}{operation__code_patriarche}-{town__numero_insee}-{section}{parcel_number}'"}),
+ 'person_raw_name': ('django.db.models.fields.TextField', [], {'default': "'{name|upper} {surname}'"}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'warehouse': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'ishtar_common.ishtaruser': {
+ 'Meta': {'object_name': 'IshtarUser', '_ormbases': ['auth.User']},
+ 'advanced_shortcut_menu': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ishtaruser'", 'unique': 'True', 'to': "orm['ishtar_common.Person']"}),
+ 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'})
+ },
+ 'ishtar_common.itemkey': {
+ 'Meta': {'object_name': 'ItemKey'},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Import']", 'null': 'True', 'blank': 'True'}),
+ 'key': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {})
+ },
+ 'ishtar_common.operationtype': {
+ 'Meta': {'ordering': "['-preventive', 'order', 'label']", 'object_name': 'OperationType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'preventive': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.organization': {
+ 'Meta': {'object_name': 'Organization'},
+ 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}),
+ 'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'history_creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'imports': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'imported_ishtar_common_organization'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['ishtar_common.Import']"}),
+ 'merge_candidate': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_candidate_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Organization']"}),
+ 'merge_exclusion': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_exclusion_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Organization']"}),
+ 'merge_key': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'organization_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.OrganizationType']"}),
+ 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.organizationtype': {
+ 'Meta': {'ordering': "('label',)", 'object_name': 'OrganizationType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.person': {
+ 'Meta': {'object_name': 'Person'},
+ 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}),
+ 'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
+ 'attached_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'members'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['ishtar_common.Organization']"}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'contact_type': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'history_creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'imports': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'imported_ishtar_common_person'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['ishtar_common.Import']"}),
+ 'merge_candidate': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_candidate_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Person']"}),
+ 'merge_exclusion': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_exclusion_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Person']"}),
+ 'merge_key': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'old_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'person_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ishtar_common.PersonType']", 'symmetrical': 'False'}),
+ 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'raw_name': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'salutation': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'surname': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'title': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.TitleType']", 'null': 'True', 'blank': 'True'}),
+ 'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.persontype': {
+ 'Meta': {'ordering': "('label',)", 'object_name': 'PersonType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.regexp': {
+ 'Meta': {'object_name': 'Regexp'},
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'regexp': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.sourcetype': {
+ 'Meta': {'object_name': 'SourceType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.state': {
+ 'Meta': {'ordering': "['number']", 'object_name': 'State'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
+ 'number': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '3'})
+ },
+ 'ishtar_common.supporttype': {
+ 'Meta': {'object_name': 'SupportType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.targetkey': {
+ 'Meta': {'unique_together': "(('target', 'key', 'associated_user', 'associated_import'),)", 'object_name': 'TargetKey'},
+ 'associated_import': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Import']", 'null': 'True', 'blank': 'True'}),
+ 'associated_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.IshtarUser']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_set': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'key': ('django.db.models.fields.TextField', [], {}),
+ 'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'keys'", 'to': "orm['ishtar_common.ImportTarget']"}),
+ 'value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.titletype': {
+ 'Meta': {'ordering': "('label',)", 'object_name': 'TitleType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.town': {
+ 'Meta': {'ordering': "['numero_insee']", 'object_name': 'Town'},
+ 'canton': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Canton']", 'null': 'True', 'blank': 'True'}),
+ 'center': ('django.contrib.gis.db.models.fields.PointField', [], {'srid': '27572', 'null': 'True', 'blank': 'True'}),
+ 'departement': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Department']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'imports': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'imported_ishtar_common_town'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['ishtar_common.Import']"}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'numero_insee': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '6'}),
+ 'surface': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ }
+ }
+
+ complete_apps = ['ishtar_common'] \ No newline at end of file
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 3453a53c5..72a3432f8 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -43,6 +43,7 @@ from django.db.utils import DatabaseError
from django.db.models import Q, Max, Count
from django.db.models.base import ModelBase
from django.db.models.signals import post_save, pre_delete, post_delete
+from django.utils.functional import lazy
from django.utils.translation import ugettext_lazy as _, ugettext, \
pgettext_lazy
@@ -66,7 +67,6 @@ from ishtar_common.data_importer import Importer, ImportFormater, \
def post_save_user(sender, **kwargs):
user = kwargs['instance']
- ishtaruser = None
try:
q = IshtarUser.objects.filter(username=user.username)
if not q.count():
@@ -334,6 +334,51 @@ class GeneralType(Cached, models.Model):
return self.label
@classmethod
+ def get_or_create(cls, slug, label=''):
+ """
+ Get or create a new item.
+
+ :param slug: textual id
+ :param label: label for initialization if the item doesn't exist (not
+ mandatory)
+
+ :return: instancied item of the base class
+ """
+
+ item = cls.get_cache(slug)
+ if item:
+ return item
+ item, created = cls.objects.get_or_create(
+ txt_idx=slug, defaults={'label': label})
+ return item
+
+ @classmethod
+ def get_or_create_pk(cls, slug):
+ """
+ Get an id from a slug. Create the associated item if needed.
+
+ :param slug: textual id
+
+ :return: id of the item (string)
+ """
+ return unicode(cls.get_or_create(slug).pk)
+
+ @classmethod
+ def get_or_create_pks(cls, slugs):
+ """
+ Get and merge a list of ids from a slug list. Create the associated
+ items if needed.
+
+ :param slugs: textual ids
+
+ :return: string with ids separated by "_"
+ """
+ items = []
+ for slug in slugs:
+ items.append(str(cls.get_or_create(slug).pk))
+ return u"_".join(items)
+
+ @classmethod
def get_help(cls, dct={}, exclude=[]):
help_text = cls.HELP_TEXT
c_rank = -1
@@ -1534,6 +1579,9 @@ class OrganizationType(GeneralType):
post_save.connect(post_save_cache, sender=OrganizationType)
post_delete.connect(post_save_cache, sender=OrganizationType)
+organization_type_pk_lazy = lazy(OrganizationType.get_or_create_pk, unicode)
+organization_type_pks_lazy = lazy(OrganizationType.get_or_create_pks, unicode)
+
IMPORTER_CLASSES = {}
IMPORTER_CLASSES.update({
@@ -1764,6 +1812,7 @@ class ImporterColumn(models.Model):
"""
Import file column description
"""
+ label = models.CharField(_(u"Label"), blank=True, null=True, max_length=200)
importer_type = models.ForeignKey(ImporterType, related_name='columns')
col_number = models.IntegerField(_(u"Column number"), default=1)
description = models.TextField(_("Description"), blank=True, null=True)
@@ -2324,6 +2373,9 @@ class PersonType(GeneralType):
post_save.connect(post_save_cache, sender=PersonType)
post_delete.connect(post_save_cache, sender=PersonType)
+person_type_pk_lazy = lazy(PersonType.get_or_create_pk, unicode)
+person_type_pks_lazy = lazy(PersonType.get_or_create_pks, unicode)
+
class TitleType(GeneralType):
class Meta:
diff --git a/ishtar_common/templates/blocks/JQueryJqGrid.html b/ishtar_common/templates/blocks/JQueryJqGrid.html
index faa2d9e93..607f81f7d 100644
--- a/ishtar_common/templates/blocks/JQueryJqGrid.html
+++ b/ishtar_common/templates/blocks/JQueryJqGrid.html
@@ -84,7 +84,7 @@ jQuery(document).ready(function(){
{{extra_cols|safe}}
],
height: 300,
- sortname: 'value',
+ sortname: '__default__',
viewrecords: true,
sortorder: "asc",
emptyrecords: "{{no_result}}",
diff --git a/ishtar_common/templates/ishtar/blocks/window_tables/dynamic_documents.html b/ishtar_common/templates/ishtar/blocks/window_tables/dynamic_documents.html
index 4a81a64fb..f751cebe3 100644
--- a/ishtar_common/templates/ishtar/blocks/window_tables/dynamic_documents.html
+++ b/ishtar_common/templates/ishtar/blocks/window_tables/dynamic_documents.html
@@ -27,7 +27,7 @@ setTimeout(
{name:'link', index:'link', width:30},
{{extra_cols|safe}}
],
- sortname: 'value',
+ sortname: '__default__',
viewrecords: true,
sortorder: "asc",
emptyrecords: "{{no_result}}",
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index bc5e5ef1d..cd34a2019 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -25,6 +25,7 @@ import cStringIO as StringIO
import datetime
import ho.pisa as pisa
import json
+import logging
from markdown import markdown
import optparse
import re
@@ -75,6 +76,8 @@ import models
CSV_OPTIONS = {'delimiter': ';', 'quotechar': '"', 'quoting': csv.QUOTE_ALL}
ENCODING = settings.ENCODING or 'utf-8'
+logger = logging.getLogger(__name__)
+
def index(request):
"""
@@ -334,7 +337,7 @@ def update_current_item(request, item_type=None, pk=None):
request.session['SHORTCUT_SEARCH'] = 'all'
currents = get_current_items(request)
- # reinit when descending item are not relevant
+ # re-init when descending item are not relevant
if item_type == 'file' and currents['file'] and currents['operation'] and \
currents['operation'].associated_file != currents['file']:
request.session["operation"] = ''
@@ -428,7 +431,6 @@ def autocomplete_person(request, person_types=None, attached_to=None,
pass
if is_ishtar_user:
query = query & Q(ishtaruser__isnull=False)
- limit = 20
persons = models.Person.objects.filter(query)[:limit]
data = json.dumps([{'id': person.pk, 'value': unicode(person)}
for person in persons if person])
@@ -696,7 +698,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
dct[k] = not dct[k]
# check also for empty value with image field
field_name = k.split('__')[0]
- # TODO: can be improved in later evrsion of Django
+ # TODO: can be improved in later version of Django
try:
c_field = model._meta.get_field(field_name)
if k.endswith('__isnull') and \
@@ -811,7 +813,6 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
items = model.objects.filter(query).distinct()
# print(items.query)
- q = request_items.get('sidx')
# table cols
if own_table_cols:
@@ -841,7 +842,12 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
manual_sort_key = None
order = request_items.get('sord')
sign = order and order == u'desc' and "-" or ''
- if q and q in request_keys:
+
+ q = request_items.get('sidx')
+ if q == '__default__' and model._meta.ordering:
+ orders = [sign + k for k in model._meta.ordering]
+ items = items.order_by(*orders)
+ elif q and q in request_keys:
ks = request_keys[q]
if type(ks) not in (list, tuple):
ks = [ks]
@@ -859,6 +865,8 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
ke = ke[0]
if ke.endswith(q):
manual_sort_key = ke
+ logger.warning("**WARN get_item - {}**: manual sort key '{"
+ "}'".format(func_name, q))
break
if not manual_sort_key and model._meta.ordering:
orders = [sign + k for k in model._meta.ordering]
@@ -903,7 +911,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
my_vals = []
for k in keys:
vals = [item]
- # foreign key may be splited by "." or "__"
+ # foreign key may be divided by "." or "__"
splitted_k = []
for ky in k.split('.'):
if '__' in ky:
@@ -973,8 +981,9 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
lnk = link_template % reverse('show-' + default_name,
args=[data[0], ''])
except NoReverseMatch:
- print '"show-' + default_name + "\" args (" + \
- unicode(data[0]) + ") url not available"
+ print(
+ '"show-' + default_name + "\" args ("
+ + unicode(data[0]) + ") url not available")
lnk = ''
res = {'id': data[0], 'link': lnk}
for idx, value in enumerate(data[1:]):
@@ -983,7 +992,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
if type(table_col) not in (list, tuple):
table_col = [table_col]
tab_cols = []
- # foreign key may be splited by "." or "__"
+ # foreign key may be divided by "." or "__"
for tc in table_col:
if '.' in tc:
tab_cols.append(tc.split('.')[-1])
@@ -1073,7 +1082,9 @@ def show_item(model, name, extra_dct=None):
dct['CURRENCY'] = get_current_profile().currency
dct['ENCODING'] = settings.ENCODING
dct['current_window_url'] = url_name
- date = 'date' in dct and dct.pop('date')
+ date = None
+ if 'date' in dct:
+ date = dct.pop('date')
dct['window_id'] = "%s-%d-%s" % (
name, item.pk, datetime.datetime.now().strftime('%M%s'))
if hasattr(item, 'history'):
@@ -1306,9 +1317,7 @@ def dashboard_main(request, dct, obj_id=None, *args, **kwargs):
return render_to_response('ishtar/dashboards/dashboard_main.html', dct,
context_instance=RequestContext(request))
-DASHBOARD_FORMS = {}
-DASHBOARD_FORMS['files'] = DashboardFormFile
-DASHBOARD_FORMS['operations'] = DashboardFormOpe
+DASHBOARD_FORMS = {'files': DashboardFormFile, 'operations': DashboardFormOpe}
def dashboard_main_detail(request, item_name):
@@ -1339,6 +1348,7 @@ def dashboard_main_detail(request, item_name):
else:
form = DASHBOARD_FORMS[item_name]()
lbl, dashboard = None, None
+ dashboard_kwargs = {}
if (item_name == 'files' and profile.files) \
or item_name == 'operations':
dashboard_kwargs = {'slice': slicing, 'fltr': fltr,
@@ -1375,7 +1385,7 @@ def dashboard_main_detail(request, item_name):
def reset_wizards(request):
- # dynamicaly execute each reset_wizards of each ishtar app
+ # dynamically execute each reset_wizards of each ishtar app
for app in settings.INSTALLED_APPS:
if app == 'ishtar_common':
# no need for infinite recursion
diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py
index 9e656311b..1183836bc 100644
--- a/ishtar_common/widgets.py
+++ b/ishtar_common/widgets.py
@@ -431,7 +431,6 @@ class JQueryPersonOrganization(forms.TextInput):
@classmethod
def encode_source(cls, source):
- encoded_src = ''
if isinstance(source, list):
encoded_src = JSONEncoder().encode(source)
elif isinstance(source, str) \
@@ -516,10 +515,29 @@ class JQueryJqGrid(forms.RadioSelect):
def __init__(self, source, form, associated_model, attrs={},
table_cols='TABLE_COLS', multiple=False, multiple_cols=[2],
new=False, new_message="", source_full=None,
- multiple_select=False):
+ multiple_select=False, sortname="__default__"):
+ """
+ JQueryJqGrid widget init.
+
+ :param source: url to get the item from -- get_item
+ :param form:
+ :param associated_model: model of the listed items
+ :param attrs:
+ :param table_cols:
+ :param multiple:
+ :param multiple_cols:
+ :param new:
+ :param new_message:
+ :param source_full: url to get full listing
+ :param multiple_select:
+ :param sortname: column name (model attribute) to use to sort
+ """
+ super(JQueryJqGrid, self).__init__(attrs=attrs)
self.source = source
self.form = form
- self.attrs = attrs
+ if not attrs:
+ attrs = {}
+ self.attrs = attrs.copy()
self.associated_model = associated_model
self.table_cols = table_cols
self.multiple = multiple
@@ -527,6 +545,7 @@ class JQueryJqGrid(forms.RadioSelect):
self.multiple_cols = multiple_cols
self.new, self.new_message = new, new_message
self.source_full = source_full
+ self.sortname = sortname
def get_cols(self, python=False):
jq_col_names, extra_cols = [], []
diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py
index c8467ca61..c065459f6 100644
--- a/ishtar_common/wizards.py
+++ b/ishtar_common/wizards.py
@@ -553,6 +553,7 @@ class Wizard(NamedUrlWizardView):
getattr(obj, k).add(adds[k])
# necessary to manage interaction between models like
# material_index management for baseitems
+ obj._cached_label_checked = False
obj.save()
m2m_items = {}
# clear
@@ -618,6 +619,7 @@ class Wizard(NamedUrlWizardView):
related_model.add(value)
# necessary to manage interaction between models like
# material_index management for baseitems
+ obj._cached_label_checked = False
obj.save()
# make the new object a default
if self.current_obj_slug:
@@ -715,7 +717,7 @@ class Wizard(NamedUrlWizardView):
# and self.form_initialized:
# for k in init[0]:
# data[step + '-' + unicode(total_field) + '-' + k] = \
- # init[0][k]
+ # init[0][k]
data = data or None
form = super(Wizard, self).get_form(step, data, files)
diff --git a/version.py b/version.py
index 56f79188c..91309b62b 100644
--- a/version.py
+++ b/version.py
@@ -1,4 +1,4 @@
-VERSION = (0, 98, 9)
+VERSION = (0, 98, 10)
def get_version():