From: Radek Czajka Date: Tue, 5 Sep 2023 13:03:30 +0000 (+0200) Subject: Reorganize depot models in preparation for more. X-Git-Url: https://git.mdrn.pl/redakcja.git/commitdiff_plain/0b1bf765d6185ef20235e702b2969d951bca4de5?ds=inline;hp=69b332800a472211b5da70426171fa429702a273 Reorganize depot models in preparation for more. --- diff --git a/src/catalogue/views.py b/src/catalogue/views.py index 80e97271..2ed4216d 100644 --- a/src/catalogue/views.py +++ b/src/catalogue/views.py @@ -384,10 +384,10 @@ def publish_collection(request, pk): @login_required def woblink_autocomplete(request, category): - shop = depot.models.Shop.objects.filter(shop='woblink').first() - if shop is None: + site = depot.models.Site.objects.filter(site_type='woblink').first() + if site is None: return JsonResponse({}) - woblink = shop.get_publisher() + woblink = site.get_publisher() term = request.GET.get('term') if not term: return JsonResponse({}) diff --git a/src/depot/admin.py b/src/depot/admin.py index ce9cc3bc..6bfd385a 100644 --- a/src/depot/admin.py +++ b/src/depot/admin.py @@ -18,16 +18,17 @@ class PriceLevelInline(OrderableAdmin, admin.TabularInline): extra = 0 -@admin.register(models.Shop) -class ShopAdmin(admin.ModelAdmin): +@admin.register(models.Site) +class SiteAdmin(admin.ModelAdmin): inlines = [ MediaInsertTextInline, PriceLevelInline, ] -@admin.register(models.ShopBookPublish) -class ShopBookPublishAdmin(admin.ModelAdmin): - list_display = ['created_at', 'book', 'user', 'shop', 'status', 'started_at', 'finished_at'] - list_filter = ['status', 'shop'] +@admin.register(models.SiteBookPublish) +class SiteBookPublishAdmin(admin.ModelAdmin): + list_display = ['created_at', 'site_book', 'user', 'status', 'started_at', 'finished_at'] + list_filter = ['status', 'site_book__site'] search_fields = ['book', 'user'] date_hierarchy = 'started_at' + raw_id_fields = ['site_book'] diff --git a/src/depot/management/commands/depot.py b/src/depot/management/commands/depot.py index 6e64e246..7087816b 100644 --- a/src/depot/management/commands/depot.py +++ b/src/depot/management/commands/depot.py @@ -1,10 +1,10 @@ from django.core.management.base import BaseCommand -from depot.models import ShopBookPublish +from depot.models import SiteBookPublish class Command(BaseCommand): def handle(self, **options): - for p in ShopBookPublish.objects.filter(status=0).order_by('created_at'): - print(p.id, p.shop, p.book.slug, p.created_at) + for p in SiteBookPublish.objects.filter(status=0).order_by('created_at'): + print(p.id, p.site_book, p.created_at) p.publish() diff --git a/src/depot/migrations/0007_rename_shopbookpublish_sitebookpublish_and_more.py b/src/depot/migrations/0007_rename_shopbookpublish_sitebookpublish_and_more.py new file mode 100644 index 00000000..06fca88c --- /dev/null +++ b/src/depot/migrations/0007_rename_shopbookpublish_sitebookpublish_and_more.py @@ -0,0 +1,44 @@ +# Generated by Django 4.1.9 on 2023-09-05 14:03 + +from django.conf import settings +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("documents", "0011_book_woblink_id"), + ("depot", "0006_shop_description_add"), + ] + + operations = [ + migrations.RenameModel( + old_name="ShopBookPublish", + new_name="SiteBookPublish", + ), + migrations.RenameModel( + old_name="ShopChunkPublish", + new_name="SiteChunkPublish", + ), + migrations.RenameField( + model_name="mediainserttext", + old_name="shop", + new_name="site", + ), + migrations.RenameField( + model_name="pricelevel", + old_name="shop", + new_name="site", + ), + migrations.RenameField( + model_name="shop", + old_name="shop", + new_name="site_type", + ), + migrations.RenameField( + model_name="sitebookpublish", + old_name="shop", + new_name="site", + ), + ] diff --git a/src/depot/migrations/0008_rename_shop_site.py b/src/depot/migrations/0008_rename_shop_site.py new file mode 100644 index 00000000..74110b1e --- /dev/null +++ b/src/depot/migrations/0008_rename_shop_site.py @@ -0,0 +1,17 @@ +# Generated by Django 4.1.9 on 2023-09-05 14:04 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("depot", "0007_rename_shopbookpublish_sitebookpublish_and_more"), + ] + + operations = [ + migrations.RenameModel( + old_name="Shop", + new_name="Site", + ), + ] diff --git a/src/depot/migrations/0009_sitebook_sitebookpublish_site_book.py b/src/depot/migrations/0009_sitebook_sitebookpublish_site_book.py new file mode 100644 index 00000000..a6aeb18f --- /dev/null +++ b/src/depot/migrations/0009_sitebook_sitebookpublish_site_book.py @@ -0,0 +1,58 @@ +# Generated by Django 4.1.9 on 2023-09-05 14:13 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("documents", "0011_book_woblink_id"), + ("depot", "0008_rename_shop_site"), + ] + + operations = [ + migrations.CreateModel( + name="SiteBook", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("external_id", models.CharField(blank=True, max_length=255)), + ("created_at", models.DateTimeField(auto_now_add=True)), + ( + "book", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="documents.book" + ), + ), + ( + "site", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="depot.site", + ), + ), + ], + options={ + "unique_together": {("book", "site")}, + }, + ), + migrations.AddField( + model_name="sitebookpublish", + name="site_book", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="depot.sitebook", + ), + ), + ] diff --git a/src/depot/migrations/0010_migrate_external_ids.py b/src/depot/migrations/0010_migrate_external_ids.py new file mode 100644 index 00000000..d00630d4 --- /dev/null +++ b/src/depot/migrations/0010_migrate_external_ids.py @@ -0,0 +1,62 @@ +# Generated by Django 4.1.9 on 2023-09-05 14:14 + +from django.db import migrations + + +def migrate_external_ids(apps, schema_editor): + Book = apps.get_model('documents', 'Book') + Site = apps.get_model('depot', 'Site') + SiteBook = apps.get_model('depot', 'SiteBook') + SiteBookPublish = apps.get_model('depot', 'SiteBookPublish') + + site_types = ('legimi', 'woblink') + for site_type in site_types: + site = Site.objects.filter(site_type=site_type).first() + if site is None: + continue + for book in Book.objects.exclude(**{f'{site_type}_id': ''}): + SiteBook.objects.get_or_create( + site=site, book=book, + external_id=getattr(book, f'{site_type}_id') + ) + + for p in SiteBookPublish.objects.all(): + p.site_book, created = SiteBook.objects.get_or_create( + site=p.site, + book=p.book + ) + p.save(update_fields=['site_book']) + + + +def remigrate_external_ids(apps, schema_editor): + Book = apps.get_model('documents', 'Book') + Site = apps.get_model('depot', 'Site') + SiteBook = apps.get_model('depot', 'SiteBook') + SiteBookPublish = apps.get_model('depot', 'SiteBookPublish') + + for p in SiteBookPublish.objects.exclude(site_book=None): + p.site = p.site_book.site + p.book = p.site_book.book + p.save(update_fields=['site', 'book']) + + site_types = ('legimi', 'woblink') + for site_type in site_types: + for site_book in SiteBook.objects.exclude(external_id=None): + book = site_book.book + setattr(book, f'{site_type}_id', site_book.external_id) + book.save(update_fields=[f'{site_type}_id']) + + +class Migration(migrations.Migration): + + dependencies = [ + ("depot", "0009_sitebook_sitebookpublish_site_book"), + ] + + operations = [ + migrations.RunPython( + migrate_external_ids, + remigrate_external_ids, + ) + ] diff --git a/src/depot/migrations/0011_remove_sitebookpublish_book_and_more.py b/src/depot/migrations/0011_remove_sitebookpublish_book_and_more.py new file mode 100644 index 00000000..df93e3f9 --- /dev/null +++ b/src/depot/migrations/0011_remove_sitebookpublish_book_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 4.1.9 on 2023-09-05 14:50 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("depot", "0010_migrate_external_ids"), + ] + + operations = [ + migrations.RemoveField( + model_name="sitebookpublish", + name="book", + ), + migrations.RemoveField( + model_name="sitebookpublish", + name="site", + ), + ] diff --git a/src/depot/models.py b/src/depot/models.py index 4b5bf654..15c0d3a8 100644 --- a/src/depot/models.py +++ b/src/depot/models.py @@ -122,10 +122,22 @@ class Package(models.Model): ) -class ShopBookPublish(models.Model): +class SiteBook(models.Model): + site = models.ForeignKey('Site', models.SET_NULL, null=True) book = models.ForeignKey('documents.Book', models.CASCADE) + external_id = models.CharField(max_length=255, blank=True) + created_at = models.DateTimeField(auto_now_add=True) + + class Meta: + unique_together = (('book', 'site'),) + + def __str__(self): + return f'{self.site} : {self.book} : {self.external_id}' + + +class SiteBookPublish(models.Model): + site_book = models.ForeignKey(SiteBook, models.PROTECT, null=True, blank=True) user = models.ForeignKey(settings.AUTH_USER_MODEL, models.SET_NULL, null=True) - shop = models.ForeignKey('Shop', models.SET_NULL, null=True) created_at = models.DateTimeField() started_at = models.DateTimeField(null=True, blank=True) finished_at = models.DateTimeField(null=True, blank=True) @@ -138,12 +150,16 @@ class ShopBookPublish(models.Model): error = models.TextField(blank=True) @classmethod - def create_for(cls, book, user, shop): + def create_for(cls, book, user, site): book.assert_publishable() changes = book.get_current_changes(publishable=True) - me = cls.objects.create(book=book, user=user, shop=shop, created_at=now()) + site_book, created = SiteBook.objects.get_or_create( + site=site, book=book + ) + me = cls.objects.create( + site_book=site_book, user=user, created_at=now()) for change in changes: - me.shopchunkpublish_set.create(change=change) + me.sitechunkpublish_set.create(change=change) return me def publish(self): @@ -153,10 +169,10 @@ class ShopBookPublish(models.Model): try: changes = [ p.change for p in - self.shopchunkpublish_set.order_by('change__chunk__number') + self.sitechunkpublish_set.order_by('change__chunk__number') ] - self.shop.publish(self.book, changes=changes) + self.site.publish(self, changes=changes) except Exception: self.status = 110 @@ -168,14 +184,14 @@ class ShopBookPublish(models.Model): self.save(update_fields=['status', 'finished_at', 'error']) -class ShopChunkPublish(models.Model): - book_publish = models.ForeignKey(ShopBookPublish, models.CASCADE) +class SiteChunkPublish(models.Model): + book_publish = models.ForeignKey(SiteBookPublish, models.CASCADE) change = models.ForeignKey('documents.ChunkChange', models.CASCADE) -class Shop(models.Model): +class Site(models.Model): name = models.CharField(max_length=255) - shop = models.CharField(max_length=32, choices=[ + site_type = models.CharField(max_length=32, choices=[ ('legimi', 'Legimi'), ('woblink', 'Woblink'), ]) @@ -185,7 +201,7 @@ class Shop(models.Model): description_add = models.TextField(blank=True) def __str__(self): - return self.shop + return self.name def get_texts(self): return [t.text for t in self.mediainserttext_set.all()] @@ -201,26 +217,32 @@ class Shop(models.Model): return price_obj.price def get_publisher(self): - if self.shop == 'legimi': + if self.site_type == 'legimi': pub_class = Legimi - elif self.shop == 'woblink': + elif self.site_type == 'woblink': pub_class = Woblink return pub_class(self.username, self.password, self.publisher_handle) - def publish(self, book, changes): + def publish(self, site_book_publish, changes): self.get_publisher().send_book( - self, book, changes=changes, + site_book_publish, + changes=changes, ) def can_publish(self, book): return self.get_publisher().can_publish(self, book) def get_last(self, book): - return self.shopbookpublish_set.filter(book=book).order_by('-created_at').first() + return SiteBookPublish.objects.filter( + site_book__site=self, site_book__book=book + ).order_by('-created_at').first() + def get_external_id_for_book(self, book): + site_book = self.sitebook_set.filter(book=book).first() + return (site_book and site_book.external_id) or '' class PriceLevel(models.Model): - shop = models.ForeignKey(Shop, models.CASCADE) + site = models.ForeignKey(Site, models.CASCADE) min_pages = models.IntegerField(null=True, blank=True) min_words = models.IntegerField(null=True, blank=True) price = models.IntegerField() @@ -230,7 +252,7 @@ class PriceLevel(models.Model): class MediaInsertText(models.Model): - shop = models.ForeignKey(Shop, models.CASCADE) + site = models.ForeignKey(Site, models.CASCADE) ordering = models.IntegerField() text = models.TextField() diff --git a/src/depot/publishers/base.py b/src/depot/publishers/base.py index dbf14ab7..5cfcbef4 100644 --- a/src/depot/publishers/base.py +++ b/src/depot/publishers/base.py @@ -17,7 +17,7 @@ class BasePublisher: self.login() return self._session - def send_book(self, shop, book, changes=None): + def send_book(self, site_book_publish, changes=None): raise NotImplementedError() def get_description(self, wlbook, description_add=''): diff --git a/src/depot/publishers/legimi.py b/src/depot/publishers/legimi.py index 2b535f92..75c21cf2 100644 --- a/src/depot/publishers/legimi.py +++ b/src/depot/publishers/legimi.py @@ -129,7 +129,7 @@ class Legimi(BasePublisher): 'Password': self.password, }) - def can_publish(self, shop, book): + def can_publish(self, site, book): meta = book.wldocument(librarian2=True).meta d = { 'errors': [], @@ -178,12 +178,15 @@ class Legimi(BasePublisher): ) return thema - def send_book(self, shop, book, changes=None): + def send_book(self, site_book_publish, changes=None): + site_book = site_book_publish.site_book + site = site_book.site + book = site_book.book wlbook = book.wldocument(librarian2=True, changes=changes) meta = wlbook.meta cover = LabelMarquiseCover(meta, width=1200).output_file() - texts = shop.get_texts() + texts = site.get_texts() epub_file = EpubBuilder( cover=MarquiseCover, fundraising=texts, @@ -206,7 +209,7 @@ class Legimi(BasePublisher): 'Isbn': '', 'LanguageLocale': lang_code_3to2(meta.language), - 'Description': self.get_description(wlbook, shop.description_add), + 'Description': self.get_description(wlbook, site.description_add), } if meta.isbn_html: isbn = meta.isbn_html @@ -243,20 +246,20 @@ class Legimi(BasePublisher): 'BookMobi.Name': mobi_data['name'], }) - if book.legimi_id: + if site_book.external_id: self.edit( - book.legimi_id, + site_book.external_id, book_data ) self.edit_files( - book.legimi_id, + site_book.external_id, files_data ) else: legimi_id = self.create_book(book_data, files_data) if legimi_id: - book.legimi_id = legimi_id - book.save(update_fields=['legimi_id']) + site_book.external_id = legimi_id + site_book.save(update_fields=['external_id']) self.edit_sale(book) diff --git a/src/depot/publishers/woblink.py b/src/depot/publishers/woblink.py index 90ee91aa..f77d6185 100644 --- a/src/depot/publishers/woblink.py +++ b/src/depot/publishers/woblink.py @@ -20,8 +20,8 @@ class WoblinkError(ValueError): class NoPrice(WoblinkError): def as_html(self): return format_html( - 'Brak określonej ceny.', - price=self.args[0].id + 'Brak określonej ceny.', + site=self.args[0].id ) class NoIsbn(WoblinkError): @@ -295,24 +295,24 @@ class Woblink(BasePublisher): def get_lang2code(self, meta, errors=None): return lang_code_3to2(meta.language) - def get_price(self, shop, wldoc, errors=None): + def get_price(self, site, wldoc, errors=None): try: stats = wldoc.get_statistics()['total'] except: if errors: - errors.append(NoPrice(shop)) + errors.append(NoPrice(site)) return 0 words = stats['words_with_fn'] pages = stats['chars_with_fn'] / 1800 - price = shop.get_price(words, pages) + price = site.get_price(words, pages) if price is None: if errors: - errors.append(NoPrice(shop)) + errors.append(NoPrice(site)) return 0 return price - def can_publish(self, shop, book): + def can_publish(self, site, book): wldoc = book.wldocument(librarian2=True) d = { 'warnings': [], @@ -320,7 +320,7 @@ class Woblink(BasePublisher): 'info': [], } errors = [] - book_data = self.get_book_data(shop, wldoc, errors) + book_data = self.get_book_data(site, wldoc, errors) for error in errors: if not isinstance(error, Warning): errlist = d['errors'] @@ -365,50 +365,53 @@ class Woblink(BasePublisher): if m is not None: return m.group(1) - def send_book(self, shop, book, changes=None): + def send_book(self, site_book_publish, changes=None): + site_book = site_book_publish.site_book + book = site_book.book + site = site_book.site wldoc = book.wldocument(librarian2=True, changes=changes, publishable=False) # TODO pub meta = wldoc.meta - book_data = self.get_book_data(shop, wldoc) + book_data = self.get_book_data(site, wldoc) - if not book.woblink_id: - #book.woblink_id = 2959868 + if not site_book.external_id: woblink_id = self.create_book(book_data['isbn']) assert woblink_id - book.woblink_id = woblink_id - book.save(update_fields=['woblink_id']) + site_book.external_id = woblink_id + site_book.save(update_fields=['external_id']) + woblink_id = site_book.external_id - self.edit_step1(book.woblink_id, book_data) - self.edit_step2(book.woblink_id, book_data) - self.edit_step3(book.woblink_id, book_data) - cover_id = self.send_cover(book.woblink_id, wldoc) + self.edit_step1(woblink_id, book_data) + self.edit_step2(woblink_id, book_data) + self.edit_step3(woblink_id, book_data) + cover_id = self.send_cover(woblink_id, wldoc) - texts = shop.get_texts() + texts = site.get_texts() epub_id, epub_demo = self.send_epub( - book.woblink_id, wldoc, book.gallery_path(), + woblink_id, wldoc, book.gallery_path(), fundraising=texts ) mobi_id, mobi_demo = self.send_mobi( - book.woblink_id, wldoc, book.gallery_path(), + woblink_id, wldoc, book.gallery_path(), fundraising=texts ) self.edit_step4( - book.woblink_id, book_data, + woblink_id, book_data, cover_id, epub_id, epub_demo, mobi_id, mobi_demo, ) - self.edit_step5(book.woblink_id, book_data) + self.edit_step5(woblink_id, book_data) - def get_book_data(self, shop, wldoc, errors=None): + def get_book_data(self, site, wldoc, errors=None): return { "title": wldoc.meta.title, "isbn": self.get_isbn(wldoc.meta, errors=errors), "authors": self.get_authors_data(wldoc.meta, errors=errors), "abstract": self.get_abstract( - wldoc, errors=errors, description_add=shop.description_add + wldoc, errors=errors, description_add=site.description_add ), "lang2code": self.get_lang2code(wldoc.meta, errors=errors), "genres": self.get_genres(wldoc.meta, errors=errors), - "price": self.get_price(shop, wldoc, errors=errors), + "price": self.get_price(site, wldoc, errors=errors), "series": self.get_series(wldoc.meta, errors=errors), } diff --git a/src/depot/templatetags/depot.py b/src/depot/templatetags/depot.py index d1194f05..25c833bd 100644 --- a/src/depot/templatetags/depot.py +++ b/src/depot/templatetags/depot.py @@ -1,20 +1,20 @@ from django.template import Library -from depot.models import Shop +from depot.models import Site register = Library() @register.simple_tag(takes_context=True) -def depot_shops(context, book): - shops = [] - for shop in Shop.objects.all(): +def depot_sites(context, book): + sites = [] + for site in Site.objects.all(): d = { - 'shop_id': shop.id, - 'name': shop.name, + 'site_id': site.id, + 'name': site.name, } - d.update(shop.can_publish(book)) - d['last'] = shop.get_last(book) - d['id'] = getattr(book, shop.shop + '_id') - shops.append(d) - return shops + d.update(site.can_publish(book)) + d['last'] = site.get_last(book) + d['id'] = site.get_external_id_for_book(book) + sites.append(d) + return sites diff --git a/src/depot/urls.py b/src/depot/urls.py index 4901ca96..ccde1291 100644 --- a/src/depot/urls.py +++ b/src/depot/urls.py @@ -3,8 +3,8 @@ from . import views urlpatterns = [ - path('shop-publish///', - views.ShopPublishView.as_view(), - name='depot_shop_publish' + path('site-publish///', + views.SitePublishView.as_view(), + name='depot_site_publish' ) ] diff --git a/src/depot/views.py b/src/depot/views.py index 79760863..5236adcf 100644 --- a/src/depot/views.py +++ b/src/depot/views.py @@ -5,14 +5,14 @@ from documents.models import Book from . import models -class ShopPublishView(PermissionRequiredMixin, View): - permission_required = 'depot.add_shopbookpublish' +class SitePublishView(PermissionRequiredMixin, View): + permission_required = 'depot.add_sitebookpublish' - def post(self, request, shop_id, book_id): - shop = get_object_or_404(models.Shop, pk=shop_id) + def post(self, request, site_id, book_id): + site = get_object_or_404(models.Site, pk=site_id) book = get_object_or_404(Book, pk=book_id) try: - publish = models.ShopBookPublish.create_for(book, request.user, shop) + publish = models.SiteBookPublish.create_for(book, request.user, site) except AssertionError: pass return redirect(book.get_absolute_url()) diff --git a/src/documents/admin.py b/src/documents/admin.py index 21390a75..673a4684 100644 --- a/src/documents/admin.py +++ b/src/documents/admin.py @@ -2,9 +2,17 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # from django.contrib import admin +import depot.models from . import models + +class SiteBookInline(admin.TabularInline): + model = depot.models.SiteBook + extra = 0 + + class BookAdmin(admin.ModelAdmin): + inlines = [SiteBookInline] list_display = ['title', 'public', '_published', '_new_publishable', 'project'] list_filter = ['public', '_published', '_new_publishable', 'project'] prepopulated_fields = {'slug': ['title']} diff --git a/src/documents/forms.py b/src/documents/forms.py index 4c970339..217a6e73 100644 --- a/src/documents/forms.py +++ b/src/documents/forms.py @@ -153,7 +153,7 @@ class BookForm(forms.ModelForm): class Meta: model = Book - exclude = ['project', 'cover', 'legimi_id', 'woblink_id'] + exclude = ['project', 'cover'] def __init__(self, *args, **kwargs): ret = super(BookForm, self).__init__(*args, **kwargs) diff --git a/src/documents/migrations/0012_remove_book_legimi_id_remove_book_woblink_id.py b/src/documents/migrations/0012_remove_book_legimi_id_remove_book_woblink_id.py new file mode 100644 index 00000000..4ccabcb4 --- /dev/null +++ b/src/documents/migrations/0012_remove_book_legimi_id_remove_book_woblink_id.py @@ -0,0 +1,21 @@ +# Generated by Django 4.1.9 on 2023-09-05 14:50 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("documents", "0011_book_woblink_id"), + ] + + operations = [ + migrations.RemoveField( + model_name="book", + name="legimi_id", + ), + migrations.RemoveField( + model_name="book", + name="woblink_id", + ), + ] diff --git a/src/documents/models/book.py b/src/documents/models/book.py index c11862ba..a13c00b2 100644 --- a/src/documents/models/book.py +++ b/src/documents/models/book.py @@ -56,8 +56,6 @@ class Book(models.Model): related_name='document_books', related_query_name='document_book', ) - legimi_id = models.CharField(max_length=255, blank=True) - woblink_id = models.CharField(max_length=255, blank=True) class NoTextError(BaseException): pass diff --git a/src/documents/templates/documents/book_detail.html b/src/documents/templates/documents/book_detail.html index 273b3a74..f534cd69 100644 --- a/src/documents/templates/documents/book_detail.html +++ b/src/documents/templates/documents/book_detail.html @@ -141,39 +141,39 @@ - {% if perms.depot.add_shopbookpublish %} - {% depot_shops book as shops %} - {% for shop in shops %} + {% if perms.depot.add_sitebookpublish %} + {% depot_sites book as sites %} + {% for site in sites %}
-

{{ shop.name }}

- {% if not shop.errors %} -
+

{{ site.name }}

+ {% if not site.errors %} + {% csrf_token %}
- {% for info in shop.info %} + {% for info in site.info %}
{{ info }}
{% endfor %} {% else %} - {% for error in shop.errors %} + {% for error in site.errors %}
{{ error }}
{% endfor %} {% endif %} - {% for warning in shop.warnings %} + {% for warning in site.warnings %}
{{ warning }}
{% endfor %} - {% if shop.id %} - id:{{ shop.id }} + {% if site.id %} + id:{{ site.id }} {% endif %} - {% with last=shop.last %} + {% with last=site.last %} {% if last %} {{ last.created_at }} → {{ last.started_at }} → @@ -181,7 +181,7 @@ ({{ last.get_status_display }}) - + {% endif %} {% endwith %} {% endfor %}