diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-05-30 20:26:21 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-06-12 09:57:24 +0200 | 
| commit | 66a376e081e335cf94ecf6fd41e5fe13a5445c57 (patch) | |
| tree | 981ddce21bc6bad956c5b012baf9608fdfe909b1 | |
| parent | 3f3c588de0995c1aec212772059f921c165abfac (diff) | |
| download | Ishtar-66a376e081e335cf94ecf6fd41e5fe13a5445c57.tar.bz2 Ishtar-66a376e081e335cf94ecf6fd41e5fe13a5445c57.zip  | |
Migrate images and sources to new document model (refs #4107)
18 files changed, 783 insertions, 131 deletions
diff --git a/archaeological_context_records/migrations/0024_auto_20180530_1900.py b/archaeological_context_records/migrations/0024_auto_20180530_1900.py new file mode 100644 index 000000000..5dac817ff --- /dev/null +++ b/archaeological_context_records/migrations/0024_auto_20180530_1900.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-05-30 19:00 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0055_auto_20180530_1900'), +        ('archaeological_context_records', '0023_auto_20180511_1232'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='contextrecord', +            name='documents', +            field=models.ManyToManyField(blank=True, related_name='context_records', to='ishtar_common.Document', verbose_name='Documents'), +        ), +        migrations.AddField( +            model_name='contextrecordsource', +            name='associated_links', +            field=models.TextField(blank=True, null=True, verbose_name='Symbolic links'), +        ), +        migrations.AddField( +            model_name='contextrecordsource', +            name='authors_raw', +            field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Authors (raw)'), +        ), +        migrations.AddField( +            model_name='contextrecordsource', +            name='index', +            field=models.IntegerField(blank=True, null=True, verbose_name='Index'), +        ), +        migrations.AddField( +            model_name='contextrecordsource', +            name='licenses', +            field=models.ManyToManyField(blank=True, to='ishtar_common.LicenseType', verbose_name='License'), +        ), +        migrations.AlterField( +            model_name='contextrecordsource', +            name='external_id', +            field=models.TextField(blank=True, null=True, verbose_name='External ID'), +        ), +        migrations.AlterField( +            model_name='contextrecordsource', +            name='internal_reference', +            field=models.TextField(blank=True, null=True, verbose_name='Internal ref.'), +        ), +        migrations.AlterField( +            model_name='contextrecordsource', +            name='reference', +            field=models.TextField(blank=True, null=True, verbose_name='Ref.'), +        ), +        migrations.AlterField( +            model_name='contextrecordsource', +            name='source_type', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SourceType', verbose_name='Type'), +        ), +        migrations.AlterField( +            model_name='contextrecordsource', +            name='title', +            field=models.TextField(blank=True, default=b'', verbose_name='Title'), +        ), +    ] diff --git a/archaeological_context_records/migrations/0025_migrate_source_and_image.py b/archaeological_context_records/migrations/0025_migrate_source_and_image.py new file mode 100644 index 000000000..c190faac2 --- /dev/null +++ b/archaeological_context_records/migrations/0025_migrate_source_and_image.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-05-30 19:22 +from __future__ import unicode_literals + +from django.db import migrations + +from ishtar_common.utils_migrations import migrate_images, migrate_sources + + +def migrate_source_and_image(apps, schema_editor): +    ContextRecord = apps.get_model( +        'archaeological_context_records', 'ContextRecord') +    ContextRecordImage = apps.get_model( +        'archaeological_context_records', 'ContextRecordImage') +    ContextRecordSource = apps.get_model( +        'archaeological_context_records', 'ContextRecordSource') +    migrate_images(apps, ContextRecord, ContextRecordImage) +    migrate_sources(apps, ContextRecord, ContextRecordSource, 'context_record') + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_context_records', '0024_auto_20180530_1900'), +    ] + +    operations = [ +        migrations.RunPython(migrate_source_and_image) +    ] diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index da488f773..b12a31516 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -30,11 +30,11 @@ from django.utils.text import slugify  from ishtar_common.utils import cached_label_changed -from ishtar_common.models import GeneralType, BaseHistorizedItem, \ -    HistoricalRecords, OwnPerms, ShortMenuItem, Source, GeneralRelationType,\ -    GeneralRecordRelations, post_delete_record_relation, get_image_path, \ -    post_save_cache, ValueGetter, BulkUpdatedItem, IshtarImage, RelationItem, \ -    Town, ThroughImage +from ishtar_common.models import BaseSource, Document, GeneralType, \ +    BaseHistorizedItem, HistoricalRecords, OwnPerms, ShortMenuItem, \ +    GeneralRelationType, GeneralRecordRelations, post_delete_record_relation,\ +    get_image_path, post_save_cache, ValueGetter, BulkUpdatedItem, \ +    IshtarImage, RelationItem, ThroughImage, Town  from archaeological_operations.models import Operation, Period, Parcel, \      ArchaeologicalSite @@ -326,6 +326,9 @@ class ContextRecord(BulkUpdatedItem, BaseHistorizedItem,      point_2d = models.PointField(_(u"Point (2D)"), blank=True, null=True)      point = models.PointField(_(u"Point (3D)"), blank=True, null=True, dim=3)      polygon = models.PolygonField(_(u"Polygon"), blank=True, null=True) +    documents = models.ManyToManyField( +        Document, related_name='context_records', verbose_name=_(u"Documents"), +        blank=True)      images = models.ManyToManyField(IshtarImage, verbose_name=_(u"Images"),                                      blank=True, through='ContextRecordImage')      cached_label = models.TextField(_(u"Cached name"), null=True, blank=True, @@ -678,11 +681,11 @@ class RecordRelationView(models.Model):          return u"{} \"{}\"".format(self.relation_type, self.right_record) -class ContextRecordSource(Source): +class ContextRecordSource(BaseSource):      SHOW_URL = 'show-contextrecordsource'      MODIFY_URL = 'record_source_modify'      TABLE_COLS = ['context_record__operation__cached_label', 'context_record']\ -        + Source.TABLE_COLS +        + BaseSource.TABLE_COLS      COL_LABELS = {'context_record__operation__cached_label': _(u"Operation")}      # search parameters @@ -708,7 +711,8 @@ class ContextRecordSource(Source):              'context_record__datings__period__pk',          'context_record__unit': 'context_record__unit__pk',      } -    PARENT_SEARCH_VECTORS = Source.PARENT_SEARCH_VECTORS + ['context_record'] +    PARENT_SEARCH_VECTORS = BaseSource.PARENT_SEARCH_VECTORS + [ +        'context_record']      class Meta:          verbose_name = _(u"Context record documentation") diff --git a/archaeological_finds/migrations/0027_auto_20180530_1900.py b/archaeological_finds/migrations/0027_auto_20180530_1900.py new file mode 100644 index 000000000..0a8181056 --- /dev/null +++ b/archaeological_finds/migrations/0027_auto_20180530_1900.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-05-30 19:00 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0055_auto_20180530_1900'), +        ('archaeological_finds', '0026_auto_20180511_1233'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='find', +            name='documents', +            field=models.ManyToManyField(blank=True, related_name='finds', to='ishtar_common.Document', verbose_name='Documents'), +        ), +        migrations.AddField( +            model_name='findsource', +            name='associated_links', +            field=models.TextField(blank=True, null=True, verbose_name='Symbolic links'), +        ), +        migrations.AddField( +            model_name='findsource', +            name='authors_raw', +            field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Authors (raw)'), +        ), +        migrations.AddField( +            model_name='findsource', +            name='index', +            field=models.IntegerField(blank=True, null=True, verbose_name='Index'), +        ), +        migrations.AddField( +            model_name='findsource', +            name='licenses', +            field=models.ManyToManyField(blank=True, to='ishtar_common.LicenseType', verbose_name='License'), +        ), +        migrations.AddField( +            model_name='treatment', +            name='documents', +            field=models.ManyToManyField(blank=True, related_name='treatments', to='ishtar_common.Document', verbose_name='Documents'), +        ), +        migrations.AddField( +            model_name='treatmentfile', +            name='documents', +            field=models.ManyToManyField(blank=True, related_name='treatment_files', to='ishtar_common.Document', verbose_name='Documents'), +        ), +        migrations.AddField( +            model_name='treatmentfilesource', +            name='associated_links', +            field=models.TextField(blank=True, null=True, verbose_name='Symbolic links'), +        ), +        migrations.AddField( +            model_name='treatmentfilesource', +            name='authors_raw', +            field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Authors (raw)'), +        ), +        migrations.AddField( +            model_name='treatmentfilesource', +            name='index', +            field=models.IntegerField(blank=True, null=True, verbose_name='Index'), +        ), +        migrations.AddField( +            model_name='treatmentfilesource', +            name='licenses', +            field=models.ManyToManyField(blank=True, to='ishtar_common.LicenseType', verbose_name='License'), +        ), +        migrations.AddField( +            model_name='treatmentsource', +            name='associated_links', +            field=models.TextField(blank=True, null=True, verbose_name='Symbolic links'), +        ), +        migrations.AddField( +            model_name='treatmentsource', +            name='authors_raw', +            field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Authors (raw)'), +        ), +        migrations.AddField( +            model_name='treatmentsource', +            name='index', +            field=models.IntegerField(blank=True, null=True, verbose_name='Index'), +        ), +        migrations.AddField( +            model_name='treatmentsource', +            name='licenses', +            field=models.ManyToManyField(blank=True, to='ishtar_common.LicenseType', verbose_name='License'), +        ), +        migrations.AlterField( +            model_name='findsource', +            name='external_id', +            field=models.TextField(blank=True, null=True, verbose_name='External ID'), +        ), +        migrations.AlterField( +            model_name='findsource', +            name='internal_reference', +            field=models.TextField(blank=True, null=True, verbose_name='Internal ref.'), +        ), +        migrations.AlterField( +            model_name='findsource', +            name='reference', +            field=models.TextField(blank=True, null=True, verbose_name='Ref.'), +        ), +        migrations.AlterField( +            model_name='findsource', +            name='source_type', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SourceType', verbose_name='Type'), +        ), +        migrations.AlterField( +            model_name='findsource', +            name='title', +            field=models.TextField(blank=True, default=b'', verbose_name='Title'), +        ), +        migrations.AlterField( +            model_name='treatmentfilesource', +            name='external_id', +            field=models.TextField(blank=True, null=True, verbose_name='External ID'), +        ), +        migrations.AlterField( +            model_name='treatmentfilesource', +            name='internal_reference', +            field=models.TextField(blank=True, null=True, verbose_name='Internal ref.'), +        ), +        migrations.AlterField( +            model_name='treatmentfilesource', +            name='reference', +            field=models.TextField(blank=True, null=True, verbose_name='Ref.'), +        ), +        migrations.AlterField( +            model_name='treatmentfilesource', +            name='source_type', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SourceType', verbose_name='Type'), +        ), +        migrations.AlterField( +            model_name='treatmentfilesource', +            name='title', +            field=models.TextField(blank=True, default=b'', verbose_name='Title'), +        ), +        migrations.AlterField( +            model_name='treatmentsource', +            name='external_id', +            field=models.TextField(blank=True, null=True, verbose_name='External ID'), +        ), +        migrations.AlterField( +            model_name='treatmentsource', +            name='internal_reference', +            field=models.TextField(blank=True, null=True, verbose_name='Internal ref.'), +        ), +        migrations.AlterField( +            model_name='treatmentsource', +            name='reference', +            field=models.TextField(blank=True, null=True, verbose_name='Ref.'), +        ), +        migrations.AlterField( +            model_name='treatmentsource', +            name='source_type', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SourceType', verbose_name='Type'), +        ), +        migrations.AlterField( +            model_name='treatmentsource', +            name='title', +            field=models.TextField(blank=True, default=b'', verbose_name='Title'), +        ), +    ] diff --git a/archaeological_finds/migrations/0028_migrate_source_and_image.py b/archaeological_finds/migrations/0028_migrate_source_and_image.py new file mode 100644 index 000000000..8f95de8ba --- /dev/null +++ b/archaeological_finds/migrations/0028_migrate_source_and_image.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-05-30 19:40 +from __future__ import unicode_literals + +from django.db import migrations + +from ishtar_common.utils_migrations import migrate_images, migrate_sources + + +def migrate_source_and_image(apps, schema_editor): +    Find = apps.get_model( +        'archaeological_finds', 'Find') +    FindImage = apps.get_model( +        'archaeological_finds', 'FindImage') +    FindSource = apps.get_model( +        'archaeological_finds', 'FindSource') +    migrate_images(apps, Find, FindImage) +    migrate_sources(apps, Find, FindSource, 'find') + +    Treatment = apps.get_model( +        'archaeological_finds', 'Treatment') +    TreatmentImage = apps.get_model( +        'archaeological_finds', 'TreatmentImage') +    TreatmentSource = apps.get_model( +        'archaeological_finds', 'TreatmentSource') +    migrate_images(apps, Treatment, TreatmentImage) +    migrate_sources(apps, Treatment, TreatmentSource, 'treatment') + +    TreatmentFile = apps.get_model( +        'archaeological_finds', 'TreatmentFile') +    TreatmentFileSource = apps.get_model( +        'archaeological_finds', 'TreatmentFileSource') +    migrate_sources(apps, TreatmentFile, TreatmentFileSource, 'treatment_file') + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_finds', '0027_auto_20180530_1900'), +    ] + +    operations = [ +        migrations.RunPython(migrate_source_and_image) +    ] diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index dadda2003..0e36cf29a 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -32,9 +32,9 @@ from django.utils.translation import ugettext_lazy as _  from ishtar_common.data_importer import post_importer_action, ImporterError  from ishtar_common.utils import cached_label_changed, post_save_point -from ishtar_common.models import GeneralType, HierarchicalType, \ -    BaseHistorizedItem, ShortMenuItem, LightHistorizedItem, \ -    HistoricalRecords, OwnPerms, Source, Person, Basket, post_save_cache, \ +from ishtar_common.models import BaseSource, Document, GeneralType, \ +    HierarchicalType, BaseHistorizedItem, ShortMenuItem, LightHistorizedItem, \ +    HistoricalRecords, OwnPerms, Person, Basket, post_save_cache, \      ValueGetter, get_current_profile, IshtarImage, ThroughImage  from archaeological_operations.models import AdministrativeAct, Operation @@ -828,6 +828,9 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,                                          null=True)      appraisal_date = models.DateField(_(u"Appraisal date"), blank=True,                                        null=True) +    documents = models.ManyToManyField( +        Document, related_name='finds', verbose_name=_(u"Documents"), +        blank=True)      images = models.ManyToManyField(IshtarImage, verbose_name=_(u"Images"),                                      blank=True, through='FindImage')      cached_label = models.TextField(_(u"Cached name"), null=True, blank=True, @@ -1443,13 +1446,13 @@ class FindImage(ThroughImage):                               related_name='associated_images') -class FindSource(Source): +class FindSource(BaseSource):      SHOW_URL = 'show-findsource'      MODIFY_URL = 'find_source_modify'      TABLE_COLS = [          'find__base_finds__context_record__operation',          'find__base_finds__context_record', 'find'] + \ -        Source.TABLE_COLS +        BaseSource.TABLE_COLS      # search parameters      BOOL_FIELDS = ['duplicate'] @@ -1475,7 +1478,7 @@ class FindSource(Source):          'find__datings__period': 'find__datings__period__pk',          'find__description': 'find__description__icontains',      } -    PARENT_SEARCH_VECTORS = Source.PARENT_SEARCH_VECTORS + ['find'] +    PARENT_SEARCH_VECTORS = BaseSource.PARENT_SEARCH_VECTORS + ['find']      class Meta:          verbose_name = _(u"Find documentation") diff --git a/archaeological_finds/models_treatments.py b/archaeological_finds/models_treatments.py index 2baced6e1..19f00de1f 100644 --- a/archaeological_finds/models_treatments.py +++ b/archaeological_finds/models_treatments.py @@ -24,17 +24,16 @@ from django.contrib.gis.db import models  from django.db.models import Max, Q  from django.db.models.signals import post_save, post_delete, pre_delete  from django.template.defaultfilters import slugify -from django.utils.translation import ugettext_lazy as _, ugettext +from django.utils.translation import ugettext_lazy as _ - -from ishtar_common.utils import cached_label_changed, get_current_year -from ishtar_common.models import GeneralType, ImageModel, BaseHistorizedItem, \ -    OwnPerms, HistoricalRecords, Person, Organization, Source, \ -    ValueGetter, post_save_cache, ShortMenuItem, DashboardFormItem, \ -    IshtarImage, ThroughImage -from archaeological_warehouse.models import Warehouse, Container  from archaeological_finds.models_finds import Find, FindBasket, TreatmentType  from archaeological_operations.models import ClosedItem, Operation +from archaeological_warehouse.models import Warehouse, Container +from ishtar_common.models import BaseSource, Document, GeneralType, \ +    ImageModel, BaseHistorizedItem, OwnPerms, HistoricalRecords, Person, \ +    Organization, ValueGetter, post_save_cache, ShortMenuItem, \ +    DashboardFormItem, IshtarImage, ThroughImage +from ishtar_common.utils import cached_label_changed, get_current_year  class TreatmentState(GeneralType): @@ -125,6 +124,9 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,                                         blank=True, null=True)      target_is_basket = models.BooleanField(_(u"Target a basket"),                                             default=False) +    documents = models.ManyToManyField( +        Document, related_name='treatments', verbose_name=_(u"Documents"), +        blank=True)      images = models.ManyToManyField(IshtarImage, verbose_name=_(u"Images"),                                      blank=True, through='TreatmentImage')      cached_label = models.TextField(_(u"Cached name"), null=True, blank=True, @@ -533,6 +535,9 @@ class TreatmentFile(DashboardFormItem, ClosedItem, BaseHistorizedItem,      reception_date = models.DateField(_(u'Reception date'), blank=True,                                        null=True)      comment = models.TextField(_(u"Comment"), null=True, blank=True) +    documents = models.ManyToManyField( +        Document, related_name='treatment_files', verbose_name=_(u"Documents"), +        blank=True)      cached_label = models.TextField(_(u"Cached name"), null=True, blank=True,                                      db_index=True)      history = HistoricalRecords() @@ -611,14 +616,14 @@ class TreatmentFile(DashboardFormItem, ClosedItem, BaseHistorizedItem,  post_save.connect(cached_label_changed, sender=TreatmentFile) -class TreatmentSource(Source): +class TreatmentSource(BaseSource):      treatment = models.ForeignKey(          Treatment, verbose_name=_(u"Treatment"), related_name="source")      BOOL_FIELDS = ['duplicate'] -    TABLE_COLS = ['treatment__cached_label'] + Source.TABLE_COLS +    TABLE_COLS = ['treatment__cached_label'] + BaseSource.TABLE_COLS      COL_LABELS = {'treatment__cached_label': _(u"Treatment")}      SHOW_URL = 'show-treatmentsource' -    PARENT_SEARCH_VECTORS = Source.PARENT_SEARCH_VECTORS + ['treatment'] +    PARENT_SEARCH_VECTORS = BaseSource.PARENT_SEARCH_VECTORS + ['treatment']      class Meta:          verbose_name = _(u"Treatment documentation") @@ -644,15 +649,16 @@ class TreatmentSource(Source):          return u"{}/source".format(self.treatment._get_base_image_path()) -class TreatmentFileSource(Source): +class TreatmentFileSource(BaseSource):      treatment_file = models.ForeignKey(          TreatmentFile, verbose_name=_(u"Treatment request"),          related_name="source")      BOOL_FIELDS = ['duplicate'] -    TABLE_COLS = ['treatment_file__cached_label'] + Source.TABLE_COLS +    TABLE_COLS = ['treatment_file__cached_label'] + BaseSource.TABLE_COLS      COL_LABELS = {'treatment_file__cached_label': _(u"Treatment file")}      SHOW_URL = 'show-treatmentfilesource' -    PARENT_SEARCH_VECTORS = Source.PARENT_SEARCH_VECTORS + ['treatment_file'] +    PARENT_SEARCH_VECTORS = BaseSource.PARENT_SEARCH_VECTORS + [ +        'treatment_file']      class Meta:          verbose_name = _(u"Treatment request documentation") diff --git a/archaeological_operations/migrations/0030_auto_20180530_1900.py b/archaeological_operations/migrations/0030_auto_20180530_1900.py new file mode 100644 index 000000000..b755c293b --- /dev/null +++ b/archaeological_operations/migrations/0030_auto_20180530_1900.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-05-30 19:00 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0055_auto_20180530_1900'), +        ('archaeological_operations', '0029_auto_20180511_1232'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='archaeologicalsite', +            name='documents', +            field=models.ManyToManyField(blank=True, related_name='sites', to='ishtar_common.Document', verbose_name='Documents'), +        ), +        migrations.AddField( +            model_name='operation', +            name='documents', +            field=models.ManyToManyField(blank=True, related_name='operations', to='ishtar_common.Document', verbose_name='Documents'), +        ), +        migrations.AddField( +            model_name='operationsource', +            name='associated_links', +            field=models.TextField(blank=True, null=True, verbose_name='Symbolic links'), +        ), +        migrations.AddField( +            model_name='operationsource', +            name='authors_raw', +            field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Authors (raw)'), +        ), +        migrations.AddField( +            model_name='operationsource', +            name='licenses', +            field=models.ManyToManyField(blank=True, to='ishtar_common.LicenseType', verbose_name='License'), +        ), +        migrations.AlterField( +            model_name='operationsource', +            name='external_id', +            field=models.TextField(blank=True, null=True, verbose_name='External ID'), +        ), +        migrations.AlterField( +            model_name='operationsource', +            name='internal_reference', +            field=models.TextField(blank=True, null=True, verbose_name='Internal ref.'), +        ), +        migrations.AlterField( +            model_name='operationsource', +            name='reference', +            field=models.TextField(blank=True, null=True, verbose_name='Ref.'), +        ), +        migrations.AlterField( +            model_name='operationsource', +            name='source_type', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SourceType', verbose_name='Type'), +        ), +        migrations.AlterField( +            model_name='operationsource', +            name='title', +            field=models.TextField(blank=True, default=b'', verbose_name='Title'), +        ), +    ] diff --git a/archaeological_operations/migrations/0031_migrate_source_and_image.py b/archaeological_operations/migrations/0031_migrate_source_and_image.py new file mode 100644 index 000000000..172e86203 --- /dev/null +++ b/archaeological_operations/migrations/0031_migrate_source_and_image.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-05-30 19:01 +from __future__ import unicode_literals + +from django.db import migrations + +from ishtar_common.utils_migrations import migrate_images, migrate_sources + + +def migrate_source_and_image(apps, schema_editor): +    ArchaeologicalSite = apps.get_model( +        'archaeological_operations', 'ArchaeologicalSite') +    SiteImage = apps.get_model('archaeological_operations', 'SiteImage') +    migrate_images(apps, ArchaeologicalSite, SiteImage) + +    Operation = apps.get_model('archaeological_operations', 'Operation') +    OperationImage = apps.get_model('archaeological_operations', +                                    'OperationImage') +    OperationSource = apps.get_model('archaeological_operations', +                                     'OperationSource') +    migrate_images(apps, Operation, OperationImage) +    migrate_sources(apps, Operation, OperationSource, 'operation') + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_operations', '0030_auto_20180530_1900'), +    ] + +    operations = [ +        migrations.RunPython(migrate_source_and_image) +    ] diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 44406fd89..de58e0da7 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -22,7 +22,6 @@ from itertools import groupby  from django.conf import settings  from django.contrib.gis.db import models -from django.core.cache import cache  from django.core.urlresolvers import reverse  from django.db import IntegrityError, transaction  from django.db.models import Q, Count, Sum, Max, Avg @@ -30,15 +29,15 @@ from django.db.models.signals import post_save, m2m_changed, post_delete  from django.forms import ValidationError  from django.utils.translation import ugettext_lazy as _, ugettext +from ishtar_common.models import BaseHistorizedItem, BaseSource, Dashboard, \ +    DashboardFormItem, Department, Document, DocumentTemplate, \ +    GeneralRecordRelations, GeneralRelationType, GeneralType, \ +    HistoricalRecords, IshtarImage, IshtarUser, LightHistorizedItem, \ +    OperationType, Organization, OwnPerms, Person, PersonType, \ +    post_delete_record_relation, post_save_cache, RelationItem, \ +    ShortMenuItem, SourceType, ThroughImage, Town, ValueGetter  from ishtar_common.utils import cached_label_changed, \ -    force_cached_label_changed, get_cache, mode - -from ishtar_common.models import GeneralType, BaseHistorizedItem, \ -    HistoricalRecords, LightHistorizedItem, OwnPerms, Department, Source,\ -    SourceType, Person, Organization, Town, Dashboard, IshtarUser, ValueGetter,\ -    DocumentTemplate, ShortMenuItem, DashboardFormItem, GeneralRelationType,\ -    GeneralRecordRelations, post_delete_record_relation, OperationType, \ -    post_save_cache, PersonType, IshtarImage, RelationItem, ThroughImage +    force_cached_label_changed, mode  class RemainType(GeneralType): @@ -129,6 +128,9 @@ class ArchaeologicalSite(BaseHistorizedItem):          _(u"Sinking date"), null=True, blank=True)      discovery_area = models.TextField(          _(u"Discovery area"), null=True, blank=True) +    documents = models.ManyToManyField( +        Document, related_name="sites", verbose_name=_(u"Documents"), +        blank=True)      images = models.ManyToManyField(IshtarImage, verbose_name=_(u"Images"),                                      through='SiteImage', blank=True) @@ -459,6 +461,9 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,      comment = models.TextField(_(u"Comment"), null=True, blank=True)      scientific_documentation_comment = models.TextField(          _(u"Comment about scientific documentation"), null=True, blank=True) +    documents = models.ManyToManyField( +        Document, related_name='operations', verbose_name=_(u"Documents"), +        blank=True)      images = models.ManyToManyField(IshtarImage, verbose_name=_(u"Images"),                                      blank=True, through='OperationImage')      cached_label = models.CharField(_(u"Cached name"), max_length=500, @@ -1039,11 +1044,11 @@ class OperationByDepartment(models.Model):          db_table = 'operation_department' -class OperationSource(Source): +class OperationSource(BaseSource):      SHOW_URL = 'show-operationsource'      MODIFY_URL = 'operation_source_modify'      TABLE_COLS = ['operation__code_patriarche', 'operation__year', -                  'operation__operation_code', 'code'] + Source.TABLE_COLS +                  'operation__operation_code', 'code'] + BaseSource.TABLE_COLS      # search parameters      BOOL_FIELDS = ['duplicate'] @@ -1063,14 +1068,11 @@ class OperationSource(Source):          'operation__operation_code': _(u"Operation code"),          'code': _(u"Document code")      } -    PARENT_SEARCH_VECTORS = Source.PARENT_SEARCH_VECTORS + ['operation'] - +    PARENT_SEARCH_VECTORS = BaseSource.PARENT_SEARCH_VECTORS + ['operation']      # fields      operation = models.ForeignKey(Operation, verbose_name=_(u"Operation"),                                    related_name="source") -    index = models.IntegerField(verbose_name=_(u"Index"), blank=True, -                                null=True)      class Meta:          verbose_name = _(u"Operation documentation") diff --git a/archaeological_warehouse/migrations/0019_warehouse_documents.py b/archaeological_warehouse/migrations/0019_warehouse_documents.py new file mode 100644 index 000000000..08ee5cb34 --- /dev/null +++ b/archaeological_warehouse/migrations/0019_warehouse_documents.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-05-30 19:00 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0055_auto_20180530_1900'), +        ('archaeological_warehouse', '0018_auto_20180528_1141'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='warehouse', +            name='documents', +            field=models.ManyToManyField(blank=True, related_name='warehouses', to='ishtar_common.Document', verbose_name='Documents'), +        ), +    ] diff --git a/archaeological_warehouse/migrations/0020_migrate_source_and_image.py b/archaeological_warehouse/migrations/0020_migrate_source_and_image.py new file mode 100644 index 000000000..1db07eee4 --- /dev/null +++ b/archaeological_warehouse/migrations/0020_migrate_source_and_image.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-05-30 19:38 +from __future__ import unicode_literals + +from django.db import migrations + + +from ishtar_common.utils_migrations import migrate_images + + +def migrate_source_and_image(apps, schema_editor): +    Warehouse = apps.get_model( +        'archaeological_warehouse', 'Warehouse') +    WarehouseImage = apps.get_model( +        'archaeological_warehouse', 'WarehouseImage') +    migrate_images(apps, Warehouse, WarehouseImage) + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_warehouse', '0019_warehouse_documents'), +    ] + +    operations = [ +        migrations.RunPython(migrate_source_and_image) +    ] diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 40de49d60..30c117fc2 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -27,11 +27,10 @@ from django.template.defaultfilters import slugify  from django.utils.translation import ugettext_lazy as _  from ishtar_common.data_importer import post_importer_action -from ishtar_common.utils import cached_label_changed - -from ishtar_common.models import GeneralType, get_external_id, \ +from ishtar_common.models import Document, GeneralType, get_external_id, \      LightHistorizedItem, OwnPerms, Address, Person, post_save_cache, \      ImageModel, DashboardFormItem, IshtarImage, ThroughImage +from ishtar_common.utils import cached_label_changed  class WarehouseType(GeneralType): @@ -63,6 +62,9 @@ class Warehouse(Address, DashboardFormItem, OwnPerms):          'WarehouseDivision', verbose_name=_("Divisions"), blank=True,          through='WarehouseDivisionLink'      ) +    documents = models.ManyToManyField( +        Document, related_name='warehouses', verbose_name=_(u"Documents"), +        blank=True)      images = models.ManyToManyField(IshtarImage, verbose_name=_(u"Images"),                                      through='WarehouseImage', blank=True)      external_id = models.TextField(_(u"External ID"), blank=True, null=True) diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py index fd0efd455..88583ad29 100644 --- a/ishtar_common/admin.py +++ b/ishtar_common/admin.py @@ -474,8 +474,7 @@ class GeneralTypeAdmin(admin.ModelAdmin):  general_models = [models.OrganizationType, models.SourceType,                    models.AuthorType, models.TitleType, models.Format, -                  models.SupportType, models.PersonType, models.LicenseType, -                  models.ImageType] +                  models.SupportType, models.PersonType, models.LicenseType]  for model in general_models:      admin_site.register(model, GeneralTypeAdmin) @@ -963,8 +962,7 @@ admin_site.register(models.AdministrationScript, AdministrationScriptAdmin)  class ImageAdmin(admin.ModelAdmin): -    list_display = ('name', 'image_type', 'reference', 'internal_reference') -    list_filter = ('image_type',) +    list_display = ('title', 'reference', 'internal_reference')      search_fields = ('name', 'reference', 'internal_reference') diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index 92c4c5797..134e7ceb1 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -1190,7 +1190,6 @@ class BaseImageForm(ManageOldType):      form_label = _(u"Images")      base_model = 'image'      associated_models = {'licence': models.LicenseType, -                         'image_type': models.ImageType,                           'authors': models.Author}      pk = forms.IntegerField(label=" ", widget=forms.HiddenInput, @@ -1198,7 +1197,6 @@ class BaseImageForm(ManageOldType):      image = forms.ImageField(          label=_(u"Image"), help_text=mark_safe(get_image_help()),          max_length=255, required=False, widget=widgets.ImageFileInput()) -    image_type = forms.ChoiceField(label=_(u"Type"), required=False, choices=[])      name = forms.CharField(label=_(u"Name"), max_length=250, required=False)      authors = widgets.Select2MultipleField(          model=models.Author, remote=True, label=_(u"Authors"), @@ -1219,7 +1217,6 @@ class BaseImageForm(ManageOldType):                                   initial=False)      TYPES = [ -        FieldType('image_type', models.ImageType, False),          FieldType('licence', models.LicenseType, True),      ] diff --git a/ishtar_common/migrations/0055_auto_20180530_1900.py b/ishtar_common/migrations/0055_auto_20180530_1900.py new file mode 100644 index 000000000..8a806fe21 --- /dev/null +++ b/ishtar_common/migrations/0055_auto_20180530_1900.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-05-30 19:00 +from __future__ import unicode_literals + +import django.contrib.postgres.search +from django.db import migrations, models +import django.db.models.deletion +import ishtar_common.models + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0054_auto_20180525_1249'), +    ] + +    operations = [ +        migrations.CreateModel( +            name='Document', +            fields=[ +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), +                ('image', models.ImageField(blank=True, max_length=255, null=True, upload_to=ishtar_common.models.get_image_path)), +                ('thumbnail', models.ImageField(blank=True, max_length=255, null=True, upload_to=ishtar_common.models.get_image_path)), +                ('search_vector', django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto filled at save', null=True, verbose_name='Search vector')), +                ('title', models.TextField(blank=True, default=b'', verbose_name='Title')), +                ('index', models.IntegerField(blank=True, null=True, verbose_name='Index')), +                ('external_id', models.TextField(blank=True, null=True, verbose_name='External ID')), +                ('reference', models.TextField(blank=True, null=True, verbose_name='Ref.')), +                ('internal_reference', models.TextField(blank=True, null=True, verbose_name='Internal ref.')), +                ('scale', models.CharField(blank=True, max_length=30, null=True, verbose_name='Scale')), +                ('authors_raw', models.CharField(blank=True, max_length=250, null=True, verbose_name='Authors (raw)')), +                ('associated_url', models.URLField(blank=True, max_length=1000, null=True, verbose_name='Numerical ressource (web address)')), +                ('receipt_date', models.DateField(blank=True, null=True, verbose_name='Receipt date')), +                ('creation_date', models.DateField(blank=True, null=True, verbose_name='Creation date')), +                ('receipt_date_in_documentation', models.DateField(blank=True, null=True, verbose_name='Receipt date in documentation')), +                ('item_number', models.IntegerField(default=1, verbose_name='Item number')), +                ('description', models.TextField(blank=True, null=True, verbose_name='Description')), +                ('comment', models.TextField(blank=True, null=True, verbose_name='Comment')), +                ('additional_information', models.TextField(blank=True, null=True, verbose_name='Additional information')), +                ('duplicate', models.BooleanField(default=False, verbose_name='Has a duplicate')), +                ('associated_links', models.TextField(blank=True, null=True, verbose_name='Symbolic links')), +                ('authors', models.ManyToManyField(related_name='document_related', to='ishtar_common.Author', verbose_name='Authors')), +                ('format_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.Format', verbose_name='Format')), +                ('licenses', models.ManyToManyField(blank=True, to='ishtar_common.LicenseType', verbose_name='License')), +            ], +            options={ +                'abstract': False, +            }, +            bases=(ishtar_common.models.OwnPerms, models.Model), +        ), +        migrations.AlterModelOptions( +            name='ishtarimage', +            options={'ordering': ('title',), 'verbose_name': 'Image', 'verbose_name_plural': 'Images'}, +        ), +        migrations.RemoveField( +            model_name='ishtarimage', +            name='image_type', +        ), +        migrations.RemoveField( +            model_name='ishtarimage', +            name='name', +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='additional_information', +            field=models.TextField(blank=True, null=True, verbose_name='Additional information'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='associated_url', +            field=models.URLField(blank=True, max_length=1000, null=True, verbose_name='Numerical ressource (web address)'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='comment', +            field=models.TextField(blank=True, null=True, verbose_name='Comment'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='duplicate', +            field=models.BooleanField(default=False, verbose_name='Has a duplicate'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='external_id', +            field=models.TextField(blank=True, null=True, verbose_name='External ID'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='format_type', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.Format', verbose_name='Format'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='index', +            field=models.IntegerField(blank=True, null=True, verbose_name='Index'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='item_number', +            field=models.IntegerField(default=1, verbose_name='Item number'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='receipt_date', +            field=models.DateField(blank=True, null=True, verbose_name='Receipt date'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='receipt_date_in_documentation', +            field=models.DateField(blank=True, null=True, verbose_name='Receipt date in documentation'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='scale', +            field=models.CharField(blank=True, max_length=30, null=True, verbose_name='Scale'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='search_vector', +            field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto filled at save', null=True, verbose_name='Search vector'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='source_type', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SourceType', verbose_name='Type'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='support_type', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SupportType', verbose_name='Support'), +        ), +        migrations.AddField( +            model_name='ishtarimage', +            name='title', +            field=models.TextField(blank=True, default=b'', verbose_name='Title'), +        ), +        migrations.AddField( +            model_name='sourcetype', +            name='parent', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SourceType', verbose_name='Parent'), +        ), +        migrations.AlterField( +            model_name='ishtarimage', +            name='authors', +            field=models.ManyToManyField(related_name='ishtarimage_related', to='ishtar_common.Author', verbose_name='Authors'), +        ), +        migrations.AlterField( +            model_name='ishtarimage', +            name='internal_reference', +            field=models.TextField(blank=True, null=True, verbose_name='Internal ref.'), +        ), +        migrations.AlterField( +            model_name='ishtarimage', +            name='reference', +            field=models.TextField(blank=True, null=True, verbose_name='Ref.'), +        ), +        migrations.DeleteModel( +            name='ImageType', +        ), +        migrations.AddField( +            model_name='document', +            name='source_type', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SourceType', verbose_name='Type'), +        ), +        migrations.AddField( +            model_name='document', +            name='support_type', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SupportType', verbose_name='Support'), +        ), +    ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index bdc621528..ef4ae63e2 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -20,54 +20,50 @@  """  Models description  """ -from cStringIO import StringIO  import copy  import datetime  import inspect -from PIL import Image  import logging  import os  import re -from secretary import Renderer as SecretaryRenderer  import shutil -from subprocess import Popen, PIPE  import tempfile  import time -from unidecode import unidecode +from cStringIO import StringIO +from subprocess import Popen, PIPE +from PIL import Image  from django.conf import settings +from django.contrib.auth.models import User, Group +from django.contrib.contenttypes.fields import GenericForeignKey +from django.contrib.contenttypes.models import ContentType +from django.contrib.gis.db import models  from django.contrib.postgres.fields import JSONField  from django.contrib.postgres.search import SearchVectorField, SearchVector  from django.core.cache import cache  from django.core.exceptions import ObjectDoesNotExist, ValidationError  from django.core.files.uploadedfile import SimpleUploadedFile -from django.core.validators import validate_slug  from django.core.urlresolvers import reverse, NoReverseMatch -from django.db.utils import DatabaseError +from django.core.validators import validate_slug  from django.db.models import Q, Max, Count  from django.db.models.signals import post_save, post_delete, m2m_changed +from django.db.utils import DatabaseError +from django.template.defaultfilters import slugify  from django.utils.functional import lazy -from django.utils.translation import ugettext_lazy as _ -  from django.utils.safestring import SafeUnicode, mark_safe -from django.template.defaultfilters import slugify - -from django.contrib.auth.models import User, Group -from django.contrib.contenttypes.models import ContentType -from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.gis.db import models - +from django.utils.translation import ugettext_lazy as _ +from secretary import Renderer as SecretaryRenderer  from simple_history.models import HistoricalRecords as BaseHistoricalRecords +from unidecode import unidecode  from ishtar_common.model_merging import merge_model_objects -from ishtar_common.utils import get_cache, disable_for_loaddata, create_slug,\ -    get_all_field_names, merge_tsvectors, cached_label_changed, \ -    generate_relation_graph -  from ishtar_common.models_imports import ImporterModel, ImporterType, \      ImporterDefault, ImporterDefaultValues, ImporterColumn, \      ImporterDuplicateField, Regexp, ImportTarget, TargetKey, FormaterType, \      Import, TargetKeyGroup +from ishtar_common.utils import get_cache, disable_for_loaddata, create_slug, \ +    get_all_field_names, merge_tsvectors, cached_label_changed, \ +    generate_relation_graph  __all__ = [      'ImporterModel', 'ImporterType', 'ImporterDefault', 'ImporterDefaultValues', @@ -3038,7 +3034,7 @@ class Author(FullSearch):              list(self.contextrecordsource_related.all()) -class SourceType(GeneralType): +class SourceType(HierarchicalType):      class Meta:          verbose_name = _(u"Source type")          verbose_name_plural = _(u"Source types") @@ -3070,11 +3066,31 @@ post_save.connect(post_save_cache, sender=Format)  post_delete.connect(post_save_cache, sender=Format) -class Source(OwnPerms, ImageModel, FullSearch): -    title = models.CharField(_(u"Title"), max_length=300) -    external_id = models.TextField(_(u"External ID"), max_length=300, null=True, -                                   blank=True) -    source_type = models.ForeignKey(SourceType, verbose_name=_(u"Type")) +class LicenseType(GeneralType): +    url = models.URLField(_(u"URL"), blank=True, null=True) + +    class Meta: +        verbose_name = _(u"License type") +        verbose_name_plural = _(u"License types") +        ordering = ('label',) + + +post_save.connect(post_save_cache, sender=LicenseType) +post_delete.connect(post_save_cache, sender=LicenseType) + + +class BaseSource(OwnPerms, ImageModel, FullSearch): +    title = models.TextField(_(u"Title"), blank=True, default='') +    index = models.IntegerField(verbose_name=_(u"Index"), blank=True, +                                null=True) +    external_id = models.TextField(_(u"External ID"), null=True, blank=True) +    reference = models.TextField(_(u"Ref."), null=True, blank=True) +    internal_reference = models.TextField(_(u"Internal ref."), null=True, +                                          blank=True) +    source_type = models.ForeignKey(SourceType, verbose_name=_(u"Type"), +                                    null=True, blank=True) +    licenses = models.ManyToManyField(LicenseType, verbose_name=_(u"License"), +                                      blank=True)      support_type = models.ForeignKey(SupportType, verbose_name=_(u"Support"),                                       blank=True, null=True,)      format_type = models.ForeignKey(Format, verbose_name=_(u"Format"), @@ -3083,6 +3099,8 @@ class Source(OwnPerms, ImageModel, FullSearch):                               blank=True)      authors = models.ManyToManyField(Author, verbose_name=_(u"Authors"),                                       related_name="%(class)s_related") +    authors_raw = models.CharField(verbose_name=_(u"Authors (raw)"), +                                   blank=True, null=True, max_length=250)      associated_url = models.URLField(          blank=True, null=True, max_length=1000,          verbose_name=_(u"Numerical ressource (web address)")) @@ -3094,15 +3112,13 @@ class Source(OwnPerms, ImageModel, FullSearch):          blank=True, null=True,          verbose_name=_(u"Receipt date in documentation"))      item_number = models.IntegerField(_(u"Item number"), default=1) -    reference = models.CharField(_(u"Ref."), max_length=100, null=True, -                                 blank=True) -    internal_reference = models.CharField( -        _(u"Internal ref."), max_length=100, null=True, blank=True)      description = models.TextField(_(u"Description"), blank=True, null=True)      comment = models.TextField(_(u"Comment"), blank=True, null=True)      additional_information = models.TextField(_(u"Additional information"),                                                blank=True, null=True)      duplicate = models.BooleanField(_(u"Has a duplicate"), default=False) +    associated_links = models.TextField(_(u"Symbolic links"), blank=True, +                                        null=True)      TABLE_COLS = ['title', 'source_type', 'authors', 'associated_url']      COL_LINK = ['associated_url'] @@ -3132,22 +3148,11 @@ class Source(OwnPerms, ImageModel, FullSearch):          return slugify(u"-".join(values)) -class LicenseType(GeneralType): -    url = models.URLField(_(u"URL"), blank=True, null=True) -    class Meta: -        verbose_name = _(u"License type") -        verbose_name_plural = _(u"License types") -        ordering = ('label',) - - -class ImageType(GeneralType): -    class Meta: -        verbose_name = _(u"Image type") -        verbose_name_plural = _(u"Image types") -        ordering = ('label',) +class Document(BaseSource): +    pass -class IshtarImage(ImageModel): +class IshtarImage(BaseSource):      # order is important: put the image in the first match found      # other will be symbolic links      RELATED_MODELS = [ @@ -3156,30 +3161,10 @@ class IshtarImage(ImageModel):      ]      LINK_SPLIT = u"<||>" -    name = models.CharField(_(u"Name"), max_length=250, blank=True, null=True) -    description = models.TextField(_(u"Description"), blank=True, null=True) -    associated_links = models.TextField(_(u"Symbolic links"), blank=True, -                                        null=True) -    licenses = models.ManyToManyField(LicenseType, verbose_name=_(u"License"), -                                      blank=True) -    authors = models.ManyToManyField(Author, verbose_name=_(u"Authors"), -                                     blank=True) -    authors_raw = models.CharField(verbose_name=_(u"Authors (raw)"), -                                   blank=True, null=True, max_length=250) - -    image_type = models.ForeignKey(ImageType, verbose_name=_(u"Type"), -                                   blank=True, null=True) -    creation_date = models.DateField(blank=True, null=True, -                                     verbose_name=_(u"Creation date")) -    reference = models.CharField(_(u"Ref."), max_length=250, null=True, -                                 blank=True) -    internal_reference = models.CharField( -        _(u"Internal ref."), max_length=250, null=True, blank=True) -      class Meta:          verbose_name = _(u"Image")          verbose_name_plural = _(u"Images") -        ordering = ('name',) +        ordering = ('title',)      def _get_base_image_paths(self):          for related_model in self.RELATED_MODELS: @@ -3314,22 +3299,22 @@ class ThroughImage(models.Model):          self.image.save() -if settings.COUNTRY == 'fr': -    class Arrondissement(models.Model): -        name = models.CharField(u"Nom", max_length=30) -        department = models.ForeignKey(Department, verbose_name=u"Département") +class Arrondissement(models.Model): +    name = models.CharField(u"Nom", max_length=30) +    department = models.ForeignKey(Department, verbose_name=u"Département") -        def __unicode__(self): -            return settings.JOINT.join((self.name, unicode(self.department))) +    def __unicode__(self): +        return settings.JOINT.join((self.name, unicode(self.department))) -    class Canton(models.Model): -        name = models.CharField(u"Nom", max_length=30) -        arrondissement = models.ForeignKey(Arrondissement, -                                           verbose_name=u"Arrondissement") -        def __unicode__(self): -            return settings.JOINT.join( -                (self.name, unicode(self.arrondissement))) +class Canton(models.Model): +    name = models.CharField(u"Nom", max_length=30) +    arrondissement = models.ForeignKey(Arrondissement, +                                       verbose_name=u"Arrondissement") + +    def __unicode__(self): +        return settings.JOINT.join( +            (self.name, unicode(self.arrondissement)))  class TownManager(models.GeoManager): diff --git a/ishtar_common/utils_migrations.py b/ishtar_common/utils_migrations.py index 9f514ea48..48e9e4f9b 100644 --- a/ishtar_common/utils_migrations.py +++ b/ishtar_common/utils_migrations.py @@ -46,3 +46,32 @@ def migrate_simple_image_to_m2m(base_model, image_model, rel_model,          print(base_model)          print("{} missing".format(missing))          print("{} moved".format(moved)) + + +def migrate_images(apps, base_model, rel_model): +    IshtarImage = apps.get_model('ishtar_common', 'IshtarImage') +    Document = apps.get_model('ishtar_common', 'Document') +    for image_rel in rel_model.objects.order_by('is_main').all(): +        image = IshtarImage.objects.get(pk=image_rel.image.pk) +        doc = Document.objects.create(image=image.image, +                                      thumbnail=image.thumbnail) +        item = base_model.objects.get(pk=image_rel.item.pk) +        item.documents.add(doc) + + +def migrate_sources(apps, base_model, source_model, item_attr): +    Document = apps.get_model('ishtar_common', 'Document') +    for source in source_model.objects.all(): +        doc = Document.objects.create() +        for attr in ['title', 'index', 'external_id', 'reference', +                     'internal_reference', 'source_type', 'support_type', +                     'format_type', 'scale', 'associated_url', 'receipt_date', +                     'creation_date', 'receipt_date_in_documentation', +                     'item_number', 'description', 'comment', +                     'additional_information', 'duplicate']: +            setattr(doc, attr, getattr(source, attr)) +        doc.save() +        for author in source.authors.all(): +            doc.authors.add(author) +        item = base_model.objects.get(pk=getattr(source, item_attr).pk) +        item.documents.add(doc)  | 
