From 62a7496b66b83284fd0dad4d59042149c99720bf Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Wed, 15 Apr 2020 17:35:51 +0300 Subject: [PATCH] Change how we handle chunk ordering (and relation). --- .../migrations/0036_auto_20200415_1420.py | 37 +++++++++++++++++++ .../migrations/0037_auto_20200415_1421.py | 23 ++++++++++++ ...38_remove_collectionitemrevision_chunks.py | 17 +++++++++ django_etesync/models.py | 14 ++++--- django_etesync/serializers.py | 18 +++++---- django_etesync/views.py | 4 +- 6 files changed, 96 insertions(+), 17 deletions(-) create mode 100644 django_etesync/migrations/0036_auto_20200415_1420.py create mode 100644 django_etesync/migrations/0037_auto_20200415_1421.py create mode 100644 django_etesync/migrations/0038_remove_collectionitemrevision_chunks.py diff --git a/django_etesync/migrations/0036_auto_20200415_1420.py b/django_etesync/migrations/0036_auto_20200415_1420.py new file mode 100644 index 0000000..a7b8003 --- /dev/null +++ b/django_etesync/migrations/0036_auto_20200415_1420.py @@ -0,0 +1,37 @@ +# Generated by Django 3.0.3 on 2020-04-15 14:20 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_etesync', '0035_auto_20200415_1259'), + ] + + operations = [ + migrations.AlterModelOptions( + name='collectionitemchunk', + options={}, + ), + migrations.AlterUniqueTogether( + name='collectionitemchunk', + unique_together=set(), + ), + migrations.CreateModel( + name='RevisionChunkRelation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('chunk', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='revisions_relation', to='django_etesync.CollectionItemChunk')), + ('revision', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='chunks_relation', to='django_etesync.CollectionItemRevision')), + ], + options={ + 'ordering': ('id',), + }, + ), + migrations.RemoveField( + model_name='collectionitemchunk', + name='order', + ), + ] diff --git a/django_etesync/migrations/0037_auto_20200415_1421.py b/django_etesync/migrations/0037_auto_20200415_1421.py new file mode 100644 index 0000000..d1a47db --- /dev/null +++ b/django_etesync/migrations/0037_auto_20200415_1421.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.3 on 2020-04-15 14:21 + +from django.db import migrations + + +def change_chunk_relation(apps, schema_editor): + CollectionItemRevision = apps.get_model('django_etesync', 'CollectionItemRevision') + RevisionChunkRelation = apps.get_model('django_etesync', 'RevisionChunkRelation') + + for revision in CollectionItemRevision.objects.all(): + for chunk in revision.chunks.all(): + RevisionChunkRelation.objects.create(chunk=chunk, revision=revision) + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_etesync', '0036_auto_20200415_1420'), + ] + + operations = [ + migrations.RunPython(change_chunk_relation), + ] diff --git a/django_etesync/migrations/0038_remove_collectionitemrevision_chunks.py b/django_etesync/migrations/0038_remove_collectionitemrevision_chunks.py new file mode 100644 index 0000000..6e35b86 --- /dev/null +++ b/django_etesync/migrations/0038_remove_collectionitemrevision_chunks.py @@ -0,0 +1,17 @@ +# Generated by Django 3.0.3 on 2020-04-15 14:34 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_etesync', '0037_auto_20200415_1421'), + ] + + operations = [ + migrations.RemoveField( + model_name='collectionitemrevision', + name='chunks', + ), + ] diff --git a/django_etesync/models.py b/django_etesync/models.py index fdf8041..449c743 100644 --- a/django_etesync/models.py +++ b/django_etesync/models.py @@ -72,13 +72,8 @@ class CollectionItemChunk(models.Model): uid = models.CharField(db_index=True, blank=False, null=False, max_length=44, validators=[Base64Url256BitValidator]) item = models.ForeignKey(CollectionItem, related_name='chunks', on_delete=models.CASCADE) - order = models.CharField(max_length=100, blank=False, null=False) chunkFile = models.FileField(upload_to=chunk_directory_path, max_length=150, unique=True) - class Meta: - unique_together = ('item', 'order') - ordering = ('item', 'order') - def __str__(self): return self.uid @@ -88,7 +83,6 @@ class CollectionItemRevision(models.Model): max_length=44, validators=[Base64Url256BitValidator]) item = models.ForeignKey(CollectionItem, related_name='revisions', on_delete=models.CASCADE) meta = models.BinaryField(editable=True, blank=False, null=False) - chunks = models.ManyToManyField(CollectionItemChunk, related_name='items') current = models.BooleanField(db_index=True, default=True, null=True) deleted = models.BooleanField(default=False) @@ -99,6 +93,14 @@ class CollectionItemRevision(models.Model): return '{} {} current={}'.format(self.uid, self.item.uid, self.current) +class RevisionChunkRelation(models.Model): + chunk = models.ForeignKey(CollectionItemChunk, related_name='revisions_relation', on_delete=models.CASCADE) + revision = models.ForeignKey(CollectionItemRevision, related_name='chunks_relation', on_delete=models.CASCADE) + + class Meta: + ordering = ('id', ) + + class CollectionMember(models.Model): class AccessLevels(models.TextChoices): ADMIN = 'adm' diff --git a/django_etesync/serializers.py b/django_etesync/serializers.py index 60c7560..f7f4b71 100644 --- a/django_etesync/serializers.py +++ b/django_etesync/serializers.py @@ -29,23 +29,23 @@ def generate_rev_uid(length=32): def process_revisions_for_item(item, revision_data): - chunks_ids = [] - chunks = revision_data.pop('chunks') + chunks_objs = [] + chunks = revision_data.pop('chunks_relation') for chunk in chunks: uid = chunk[0] if len(chunk) > 1: content = chunk[1] - # FIXME: fix order! - chunk = models.CollectionItemChunk(uid=uid, item=item, order='abc') + chunk = models.CollectionItemChunk(uid=uid, item=item) chunk.chunkFile.save('IGNORED', ContentFile(content)) chunk.save() - chunks_ids.append(chunk.id) + chunks_objs.append(chunk) else: chunk = models.CollectionItemChunk.objects.get(uid=uid) - chunks_ids.append(chunk.id) + chunks_objs.append(chunk) revision = models.CollectionItemRevision.objects.create(**revision_data, item=item) - revision.chunks.set(chunks_ids) + for chunk in chunks_objs: + models.RevisionChunkRelation.objects.create(chunk=chunk, revision=revision) return revision @@ -84,6 +84,7 @@ class CollectionContentField(BinaryBase64Field): class ChunksField(serializers.RelatedField): def to_representation(self, obj): + obj = obj.chunk inline = self.context.get('inline', False) if inline: with open(obj.chunkFile.path, 'rb') as f: @@ -103,7 +104,8 @@ class CollectionItemChunkSerializer(serializers.ModelSerializer): class CollectionItemRevisionSerializer(serializers.ModelSerializer): chunks = ChunksField( - queryset=models.CollectionItemChunk.objects.all(), + source='chunks_relation', + queryset=models.RevisionChunkRelation.objects.all(), many=True ) meta = BinaryBase64Field() diff --git a/django_etesync/views.py b/django_etesync/views.py index 1c9da78..c4c8479 100644 --- a/django_etesync/views.py +++ b/django_etesync/views.py @@ -186,9 +186,7 @@ class CollectionItemChunkViewSet(viewsets.ViewSet): serializer = self.serializer_class(data=request.data) if serializer.is_valid(): try: - # FIXME: actually generate the correct order value. Or alternatively have it null at first and only - # set it when ommitting to a snapshot - serializer.save(item=col_it, order='abc') + serializer.save(item=col_it) except IntegrityError: content = {'code': 'integrity_error'} return Response(content, status=status.HTTP_400_BAD_REQUEST)