from django.db import models from django.utils.translation import gettext_lazy as _ from filer.fields.image import FilerImageField class BookCollection(models.Model): class DisplayPosition(models.TextChoices): PINNED = 'pinned', _('Pinned') MIDDLE = 'middle', _('Middle Section') BOTTOM = 'bottom', _('Bottom Section') title = models.CharField(max_length=255) summary = models.CharField(max_length=512, null=True, blank=True, help_text=_('could be null')) display_position = models.CharField( max_length=20, choices=DisplayPosition.choices, default=DisplayPosition.PINNED, verbose_name=_('Display Position') ) status = models.BooleanField(_('status'), default=True) order = models.IntegerField(default=0, verbose_name=_('order')) books = models.ManyToManyField('library.Book', related_name='related_collections_books',through="library.Book_collections" ,verbose_name=_('Books'), blank=True) def __str__(self): return f'Collection #{self.id}/{self.title}' class Meta: verbose_name = _('Book Collection') verbose_name_plural = _('Book Collections') class PinnedBookCollection(BookCollection): """ Proxy model for pinned book collections """ class Meta: proxy = True verbose_name = _('Pinned Book Collection') verbose_name_plural = _('Pinned Book Collections') class MiddleBookCollection(BookCollection): """ Proxy model for middle section book collections """ class Meta: proxy = True verbose_name = _('Middle Section Book Collection') verbose_name_plural = _('Middle Section Book Collections') class BottomBookCollection(BookCollection): """ Proxy model for bottom section book collections """ class Meta: proxy = True verbose_name = _('Bottom Section Book Collection') verbose_name_plural = _('Bottom Section Book Collections') class Category(models.Model): title = models.CharField(max_length=255) slug = models.SlugField(max_length=255, unique=True) status = models.BooleanField(default=True, verbose_name=_('status')) # books = models.ManyToManyField('library.Book', related_name='related_categories_books',through="library.Book_categories" ,verbose_name=_('Books'), blank=True) created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('created at')) updated_at = models.DateTimeField(auto_now=True, verbose_name=_('updated at')) def __str__(self): return self.title @property def books_count(self): """Return the number of books in this category""" return self.related_categories.count() class Meta: verbose_name = _('Category') verbose_name_plural = _('Categories') class Book(models.Model): class FileType(models.TextChoices): pdf = 'pdf', 'Pdf' epub = 'epub', 'Epub' docx = 'docx', 'Docx' title = models.CharField(max_length=255) slug = models.SlugField(max_length=255, unique=True) summary = models.CharField(max_length=512, null=True, blank=True, help_text=_('could be null')) description = models.TextField(null=True, blank=True, help_text=_('could be null')) thumbnail = models.ImageField(upload_to='book_thumbnails/', null=True, blank=True, help_text=_('image allowed')) author = models.CharField(max_length=255, null=True, blank=True) pages_count = models.CharField(verbose_name=_('Number of Pages'), max_length=255, help_text=_('eg. 34'), null=True) status = models.BooleanField(default=True, verbose_name=_('status')) pin = models.BooleanField(default=True, verbose_name=_('Pin to top')) categories = models.ManyToManyField(Category, related_name='related_categories', verbose_name=_('categories'), blank=True) collections = models.ManyToManyField(BookCollection, related_name='related_collections', verbose_name=_('collections'), blank=True) view_count = models.PositiveBigIntegerField(default=0, verbose_name=_('view count')) download_count = models.PositiveBigIntegerField(default=0, verbose_name=_('view count')) # seo_fields = SeoGenericRelation(verbose_name=_('soe fields')) file_type = models.CharField(verbose_name=_('File Type'), choices=FileType.choices, default=FileType.pdf, max_length=16) book_file = models.FileField(null=True, blank=True, max_length=550, upload_to='books', verbose_name='Book File') created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('created at')) updated_at = models.DateTimeField(auto_now=True, verbose_name=_('updated at')) def __str__(self): return f'<{self.id}>-{self.title}' def increment_view_count(self): """Increment the view count by 1 and save the model""" self.view_count += 1 self.save(update_fields=['view_count']) class Meta: verbose_name = _('Book') verbose_name_plural = _('Books')