Make the field migrations work.
authorRadek Czajka <rczajka@rczajka.pl>
Mon, 3 Oct 2022 08:11:36 +0000 (10:11 +0200)
committerRadek Czajka <rczajka@rczajka.pl>
Mon, 3 Oct 2022 08:11:36 +0000 (10:11 +0200)
src/catalogue/fields.py
src/catalogue/migrations/0038_auto_20220930_1050.py

index 38cac77..aaa322d 100644 (file)
@@ -69,14 +69,20 @@ class EbookField(models.FileField):
     librarian2_api = False
     ZIP = None
 
-    def __init__(self, verbose_name_=None, with_etag=True, **kwargs):
+    def __init__(self, verbose_name_=None, with_etag=True, etag_field_name=None, **kwargs):
         # This is just for compatibility with older migrations,
         # where first argument was for ebook format.
         # Can be scrapped if old migrations are updated/removed.
         verbose_name = verbose_name_ or _("%s file") % self.ext
         kwargs.setdefault('verbose_name', verbose_name_ )
 
+        # Another compatibility fix:
+        # old migrations use EbookField directly, creating etag fields.
+        if type(self) is EbookField:
+            with_etag = False
+
         self.with_etag = with_etag
+        self.etag_field_name = etag_field_name
         kwargs.setdefault('max_length', 255)
         kwargs.setdefault('blank', True)
         kwargs.setdefault('default', '')
@@ -94,8 +100,14 @@ class EbookField(models.FileField):
             del kwargs['default']
         if self.get_upload_to(self.ext) == kwargs.get('upload_to'):
             del kwargs['upload_to']
-        if not self.with_etag:
+        # with_etag creates a second field, which then deconstructs to manage
+        # its own migrations. So for migrations, etag_field_name is explicitly
+        # set to avoid double creation of the etag field.
+        if self.with_etag:
+            kwargs['etag_field_name'] = self.etag_field_name
+        else:
             kwargs['with_etag'] = self.with_etag
+
         # Compatibility
         verbose_name = kwargs.get('verbose_name')
         if verbose_name:
@@ -114,8 +126,8 @@ class EbookField(models.FileField):
     def contribute_to_class(self, cls, name):
         super(EbookField, self).contribute_to_class(cls, name)
 
-        self.etag_field_name = f'{name}_etag'
-        if self.with_etag:
+        if self.with_etag and not self.etag_field_name:
+            self.etag_field_name = f'{name}_etag'
             self.etag_field = models.CharField(max_length=255, editable=False, default='', db_index=True)
             self.etag_field.contribute_to_class(cls, f'{name}_etag')
 
@@ -221,7 +233,7 @@ class PdfField(EbookField):
             base_url=absolute_url(gallery_url(wldoc.book_info.url.slug)), customizations=['notoc'])
 
     def build(self, fieldfile):
-        BuildEbook.build(self, fieldfile)
+        super().build(fieldfile)
         clear_cache(fieldfile.instance.slug)
 
 
index 4963e66..47e904a 100644 (file)
@@ -15,62 +15,62 @@ class Migration(migrations.Migration):
         migrations.AlterField(
             model_name='book',
             name='cover',
-            field=catalogue.fields.CoverField('cover', storage=fnpdjango.storage.BofhFileSystemStorage()),
+            field=catalogue.fields.CoverField('cover', etag_field_name='cover_etag', storage=fnpdjango.storage.BofhFileSystemStorage()),
         ),
         migrations.AlterField(
             model_name='book',
             name='cover_api_thumb',
-            field=catalogue.fields.CoverApiThumbField('cover thumbnail for mobile app'),
+            field=catalogue.fields.CoverApiThumbField('cover thumbnail for mobile app', etag_field_name='cover_api_thumb_etag'),
         ),
         migrations.AlterField(
             model_name='book',
             name='cover_clean',
-            field=catalogue.fields.CoverCleanField('clean cover'),
+            field=catalogue.fields.CoverCleanField('clean cover', etag_field_name='cover_clean_etag'),
         ),
         migrations.AlterField(
             model_name='book',
             name='cover_ebookpoint',
-            field=catalogue.fields.CoverEbookpointField('cover for Ebookpoint'),
+            field=catalogue.fields.CoverEbookpointField('cover for Ebookpoint', etag_field_name='cover_ebookpoint_etag'),
         ),
         migrations.AlterField(
             model_name='book',
             name='cover_thumb',
-            field=catalogue.fields.CoverThumbField('cover thumbnail'),
+            field=catalogue.fields.CoverThumbField('cover thumbnail', etag_field_name='cover_thumb_etag'),
         ),
         migrations.AlterField(
             model_name='book',
             name='epub_file',
-            field=catalogue.fields.EpubField(storage=fnpdjango.storage.BofhFileSystemStorage()),
+            field=catalogue.fields.EpubField(etag_field_name='epub_file_etag', storage=fnpdjango.storage.BofhFileSystemStorage()),
         ),
         migrations.AlterField(
             model_name='book',
             name='fb2_file',
-            field=catalogue.fields.Fb2Field(storage=fnpdjango.storage.BofhFileSystemStorage()),
+            field=catalogue.fields.Fb2Field(etag_field_name='fb2_file_etag', storage=fnpdjango.storage.BofhFileSystemStorage()),
         ),
         migrations.AlterField(
             model_name='book',
             name='html_file',
-            field=catalogue.fields.HtmlField(storage=fnpdjango.storage.BofhFileSystemStorage()),
+            field=catalogue.fields.HtmlField(etag_field_name='html_file_etag', storage=fnpdjango.storage.BofhFileSystemStorage()),
         ),
         migrations.AlterField(
             model_name='book',
             name='mobi_file',
-            field=catalogue.fields.MobiField(storage=fnpdjango.storage.BofhFileSystemStorage()),
+            field=catalogue.fields.MobiField(etag_field_name='mobi_file_etag', storage=fnpdjango.storage.BofhFileSystemStorage()),
         ),
         migrations.AlterField(
             model_name='book',
             name='pdf_file',
-            field=catalogue.fields.PdfField(storage=fnpdjango.storage.BofhFileSystemStorage()),
+            field=catalogue.fields.PdfField(etag_field_name='pdf_file_etag', storage=fnpdjango.storage.BofhFileSystemStorage()),
         ),
         migrations.AlterField(
             model_name='book',
             name='simple_cover',
-            field=catalogue.fields.SimpleCoverField('cover for mobile app'),
+            field=catalogue.fields.SimpleCoverField('cover for mobile app', etag_field_name='simple_cover_etag'),
         ),
         migrations.AlterField(
             model_name='book',
             name='txt_file',
-            field=catalogue.fields.TxtField(storage=fnpdjango.storage.BofhFileSystemStorage()),
+            field=catalogue.fields.TxtField(etag_field_name='txt_file_etag', storage=fnpdjango.storage.BofhFileSystemStorage()),
         ),
         migrations.AlterField(
             model_name='book',