2020-05-01 22:46:15 +08:00
|
|
|
import django.contrib.postgres.fields as postgres
|
2021-12-24 11:56:04 -08:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2020-05-01 22:46:15 +08:00
|
|
|
from django.db import models
|
2020-11-23 23:18:14 +01:00
|
|
|
from django.shortcuts import reverse
|
|
|
|
from common.models import Entity, Mark, Review, Tag
|
2021-08-01 12:36:03 +02:00
|
|
|
from common.utils import GenerateDateUUIDMediaFilePath
|
2021-09-10 20:24:22 -04:00
|
|
|
from django.conf import settings
|
2021-09-23 22:16:17 -04:00
|
|
|
from django.db.models import Q
|
2020-05-01 22:46:15 +08:00
|
|
|
|
|
|
|
|
|
|
|
def book_cover_path(instance, filename):
|
2021-09-10 20:24:22 -04:00
|
|
|
return GenerateDateUUIDMediaFilePath(instance, filename, settings.BOOK_MEDIA_PATH_ROOT)
|
2020-05-01 22:46:15 +08:00
|
|
|
|
|
|
|
|
2020-11-23 23:18:14 +01:00
|
|
|
class Book(Entity):
|
2020-05-01 22:46:15 +08:00
|
|
|
# widely recognized name, usually in Chinese
|
|
|
|
title = models.CharField(_("title"), max_length=200)
|
2022-04-03 12:05:48 -04:00
|
|
|
subtitle = models.CharField(
|
|
|
|
_("subtitle"), blank=True, default='', max_length=200)
|
2020-05-01 22:46:15 +08:00
|
|
|
# original name, for books in foreign language
|
2022-04-03 12:05:48 -04:00
|
|
|
orig_title = models.CharField(
|
|
|
|
_("original title"), blank=True, default='', max_length=200)
|
2020-05-01 22:46:15 +08:00
|
|
|
|
|
|
|
author = postgres.ArrayField(
|
|
|
|
models.CharField(_("author"), blank=True, default='', max_length=100),
|
|
|
|
null=True,
|
|
|
|
blank=True,
|
|
|
|
default=list,
|
|
|
|
)
|
|
|
|
translator = postgres.ArrayField(
|
2022-04-03 12:05:48 -04:00
|
|
|
models.CharField(_("translator"), blank=True,
|
|
|
|
default='', max_length=100),
|
2020-05-01 22:46:15 +08:00
|
|
|
null=True,
|
|
|
|
blank=True,
|
|
|
|
default=list,
|
|
|
|
)
|
2022-04-03 12:05:48 -04:00
|
|
|
language = models.CharField(
|
|
|
|
_("language"), blank=True, default='', max_length=10)
|
|
|
|
pub_house = models.CharField(
|
|
|
|
_("publishing house"), blank=True, default='', max_length=200)
|
2020-05-01 22:46:15 +08:00
|
|
|
pub_year = models.IntegerField(_("published year"), null=True, blank=True)
|
2022-04-03 12:05:48 -04:00
|
|
|
pub_month = models.IntegerField(
|
|
|
|
_("published month"), null=True, blank=True)
|
|
|
|
binding = models.CharField(
|
|
|
|
_("binding"), blank=True, default='', max_length=50)
|
2020-05-01 22:46:15 +08:00
|
|
|
# since data origin is not formatted and might be CNY USD or other currency, use char instead
|
2022-04-03 12:05:48 -04:00
|
|
|
price = models.CharField(_("pricing"), blank=True,
|
|
|
|
default='', max_length=50)
|
2020-05-01 22:46:15 +08:00
|
|
|
pages = models.PositiveIntegerField(_("pages"), null=True, blank=True)
|
2022-04-03 12:05:48 -04:00
|
|
|
isbn = models.CharField(_("ISBN"), blank=True, null=False,
|
|
|
|
max_length=20, db_index=True, default='')
|
|
|
|
# to store previously scrapped data
|
|
|
|
cover = models.ImageField(_("cover picture"), upload_to=book_cover_path,
|
|
|
|
default=settings.DEFAULT_BOOK_IMAGE, blank=True)
|
2020-07-05 20:52:30 +08:00
|
|
|
contents = models.TextField(blank=True, default="")
|
2020-05-01 22:46:15 +08:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
constraints = [
|
2022-04-03 12:05:48 -04:00
|
|
|
models.CheckConstraint(check=models.Q(
|
|
|
|
pub_year__gte=0), name='pub_year_lowerbound'),
|
|
|
|
models.CheckConstraint(check=models.Q(
|
|
|
|
pub_month__lte=12), name='pub_month_upperbound'),
|
|
|
|
models.CheckConstraint(check=models.Q(
|
|
|
|
pub_month__gte=1), name='pub_month_lowerbound'),
|
2020-05-01 22:46:15 +08:00
|
|
|
]
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.title
|
2022-04-03 12:05:48 -04:00
|
|
|
|
2022-02-20 19:09:23 -05:00
|
|
|
def get_json(self):
|
|
|
|
r = {
|
|
|
|
'subtitle': self.subtitle,
|
|
|
|
'original_title': self.orig_title,
|
|
|
|
'author': self.author,
|
|
|
|
'translator': self.translator,
|
|
|
|
'publisher': self.pub_house,
|
|
|
|
'publish_year': self.pub_year,
|
|
|
|
'publish_month': self.pub_month,
|
|
|
|
'language': self.language,
|
|
|
|
'isbn': self.isbn,
|
|
|
|
}
|
|
|
|
r.update(super().get_json())
|
|
|
|
return r
|
|
|
|
|
2020-11-23 23:18:14 +01:00
|
|
|
def get_absolute_url(self):
|
|
|
|
return reverse("books:retrieve", args=[self.id])
|
2020-05-01 22:46:15 +08:00
|
|
|
|
2020-07-10 21:28:09 +08:00
|
|
|
def get_tags_manager(self):
|
|
|
|
return self.book_tags
|
|
|
|
|
2021-09-23 22:16:17 -04:00
|
|
|
def get_related_books(self):
|
2022-04-03 12:05:48 -04:00
|
|
|
qs = Q(orig_title=self.title)
|
2021-09-23 22:16:17 -04:00
|
|
|
if self.isbn:
|
2022-04-03 12:05:48 -04:00
|
|
|
qs = qs | Q(isbn=self.isbn)
|
2021-09-23 22:16:17 -04:00
|
|
|
if self.orig_title:
|
2022-04-03 12:05:48 -04:00
|
|
|
qs = qs | Q(title=self.orig_title)
|
|
|
|
qs = qs | Q(orig_title=self.orig_title)
|
|
|
|
qs = qs & ~Q(id=self.id)
|
2021-09-23 22:16:17 -04:00
|
|
|
return Book.objects.filter(qs)
|
|
|
|
|
2022-04-03 12:05:48 -04:00
|
|
|
def get_identicals(self):
|
|
|
|
qs = Q(orig_title=self.title)
|
|
|
|
if self.isbn:
|
|
|
|
qs = Q(isbn=self.isbn)
|
|
|
|
# qs = qs & ~Q(id=self.id)
|
|
|
|
return Book.objects.filter(qs)
|
|
|
|
else:
|
|
|
|
return [self] # Book.objects.filter(id=self.id)
|
|
|
|
|
2020-10-04 16:16:50 +02:00
|
|
|
@property
|
|
|
|
def verbose_category_name(self):
|
|
|
|
return _("书籍")
|
|
|
|
|
2020-05-01 22:46:15 +08:00
|
|
|
|
|
|
|
class BookMark(Mark):
|
2022-04-03 12:05:48 -04:00
|
|
|
book = models.ForeignKey(
|
|
|
|
Book, on_delete=models.CASCADE, related_name='book_marks', null=True)
|
|
|
|
|
2020-05-01 22:46:15 +08:00
|
|
|
class Meta:
|
|
|
|
constraints = [
|
2022-04-03 12:05:48 -04:00
|
|
|
models.UniqueConstraint(
|
|
|
|
fields=['owner', 'book'], name="unique_book_mark")
|
2020-05-01 22:46:15 +08:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
class BookReview(Review):
|
2022-04-03 12:05:48 -04:00
|
|
|
book = models.ForeignKey(
|
|
|
|
Book, on_delete=models.CASCADE, related_name='book_reviews', null=True)
|
|
|
|
|
2020-05-01 22:46:15 +08:00
|
|
|
class Meta:
|
|
|
|
constraints = [
|
2022-04-03 12:05:48 -04:00
|
|
|
models.UniqueConstraint(
|
|
|
|
fields=['owner', 'book'], name="unique_book_review")
|
|
|
|
]
|
2020-07-10 21:28:09 +08:00
|
|
|
|
|
|
|
|
|
|
|
class BookTag(Tag):
|
2022-04-03 12:05:48 -04:00
|
|
|
book = models.ForeignKey(
|
|
|
|
Book, on_delete=models.CASCADE, related_name='book_tags', null=True)
|
|
|
|
mark = models.ForeignKey(
|
|
|
|
BookMark, on_delete=models.CASCADE, related_name='bookmark_tags', null=True)
|
|
|
|
|
2020-07-10 21:28:09 +08:00
|
|
|
class Meta:
|
|
|
|
constraints = [
|
2022-04-03 12:05:48 -04:00
|
|
|
models.UniqueConstraint(
|
|
|
|
fields=['content', 'mark'], name="unique_bookmark_tag")
|
2020-10-04 16:16:50 +02:00
|
|
|
]
|