2019-08-02 12:57:53 +00:00
|
|
|
# -*- mode: python; coding: utf-8 -*-
|
2021-11-14 13:26:41 +00:00
|
|
|
# Copyright (C) 2017-2021 by BDE ENS Paris-Saclay
|
2019-08-02 12:57:53 +00:00
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
2021-11-14 13:26:41 +00:00
|
|
|
from django.conf import settings
|
2017-07-03 23:47:22 +00:00
|
|
|
from django.core.validators import MinValueValidator
|
2019-08-02 12:57:53 +00:00
|
|
|
from django.db import models
|
|
|
|
from django.utils.translation import gettext_lazy as _
|
2021-10-26 09:37:32 +00:00
|
|
|
from polymorphic.models import PolymorphicModel
|
2019-08-02 12:57:53 +00:00
|
|
|
|
2019-08-11 07:22:22 +00:00
|
|
|
from .fields import ISBNField
|
|
|
|
|
2017-06-30 01:25:07 +00:00
|
|
|
|
2021-10-23 16:31:03 +00:00
|
|
|
class Author(models.Model):
|
2019-08-16 12:01:13 +00:00
|
|
|
name = models.CharField(
|
|
|
|
max_length=255,
|
|
|
|
unique=True,
|
|
|
|
verbose_name=_('name'),
|
|
|
|
)
|
2017-06-30 01:25:07 +00:00
|
|
|
|
2020-02-10 16:27:30 +00:00
|
|
|
note = models.IntegerField(
|
|
|
|
default=0,
|
|
|
|
verbose_name=_("note"),
|
|
|
|
)
|
|
|
|
|
2017-06-30 01:25:07 +00:00
|
|
|
def __str__(self):
|
2019-08-16 12:01:13 +00:00
|
|
|
return self.name
|
2017-06-30 01:25:07 +00:00
|
|
|
|
2019-08-02 12:57:53 +00:00
|
|
|
class Meta:
|
|
|
|
verbose_name = _("author")
|
|
|
|
verbose_name_plural = _("authors")
|
2019-08-16 12:01:13 +00:00
|
|
|
ordering = ['name']
|
2019-08-02 12:57:53 +00:00
|
|
|
|
|
|
|
|
2021-10-26 09:37:32 +00:00
|
|
|
class Borrowable(PolymorphicModel):
|
2021-11-02 11:32:31 +00:00
|
|
|
isbn = ISBNField(
|
|
|
|
_('ISBN'),
|
|
|
|
help_text=_('You may be able to scan it from a bar code.'),
|
|
|
|
unique=True,
|
|
|
|
blank=True,
|
|
|
|
null=True,
|
|
|
|
)
|
|
|
|
|
2021-10-26 09:37:32 +00:00
|
|
|
title = models.CharField(
|
|
|
|
max_length=255,
|
|
|
|
verbose_name=_("title"),
|
|
|
|
)
|
|
|
|
|
|
|
|
present = models.BooleanField(
|
|
|
|
verbose_name=_("present"),
|
|
|
|
help_text=_("Tell that the medium is present in the Mediatek."),
|
|
|
|
default=False,
|
|
|
|
)
|
|
|
|
|
|
|
|
def __str__(self):
|
2021-10-26 13:07:37 +00:00
|
|
|
obj = self
|
|
|
|
if obj.__class__ == Borrowable:
|
|
|
|
# Get true object instance, useful for autocompletion
|
|
|
|
obj = Borrowable.objects.get(pk=obj.pk)
|
|
|
|
|
|
|
|
title = obj.title
|
|
|
|
if hasattr(obj, 'subtitle'):
|
|
|
|
subtitle = obj.subtitle
|
|
|
|
if subtitle:
|
|
|
|
title = f"{title} : {subtitle}"
|
|
|
|
return title
|
2021-10-26 09:37:32 +00:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _('borrowable')
|
|
|
|
verbose_name_plural = _('borrowables')
|
|
|
|
|
|
|
|
|
|
|
|
class Medium(Borrowable):
|
|
|
|
external_url = models.URLField(
|
|
|
|
verbose_name=_('external URL'),
|
|
|
|
blank=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
side_identifier = models.CharField(
|
|
|
|
verbose_name=_('side identifier'),
|
|
|
|
max_length=255,
|
|
|
|
)
|
|
|
|
|
|
|
|
authors = models.ManyToManyField(
|
|
|
|
'Author',
|
|
|
|
verbose_name=_('authors'),
|
|
|
|
)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("medium")
|
|
|
|
verbose_name_plural = _("media")
|
|
|
|
|
|
|
|
|
|
|
|
class Book(Medium):
|
|
|
|
subtitle = models.CharField(
|
|
|
|
verbose_name=_('subtitle'),
|
|
|
|
max_length=255,
|
|
|
|
blank=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
number_of_pages = models.PositiveIntegerField(
|
|
|
|
verbose_name=_('number of pages'),
|
|
|
|
blank=True,
|
|
|
|
null=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
publish_date = models.DateField(
|
|
|
|
verbose_name=_('publish date'),
|
|
|
|
blank=True,
|
|
|
|
null=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("book")
|
|
|
|
verbose_name_plural = _("books")
|
|
|
|
|
|
|
|
|
|
|
|
class Comic(Book):
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("comic")
|
|
|
|
verbose_name_plural = _("comics")
|
|
|
|
ordering = ['title', 'subtitle']
|
|
|
|
|
|
|
|
|
|
|
|
class Manga(Book):
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("manga")
|
|
|
|
verbose_name_plural = _("mangas")
|
|
|
|
ordering = ['title', 'subtitle']
|
|
|
|
|
|
|
|
|
|
|
|
class Novel(Book):
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("novel")
|
|
|
|
verbose_name_plural = _("novels")
|
|
|
|
ordering = ['title', 'subtitle']
|
|
|
|
|
|
|
|
|
|
|
|
class Vinyl(Medium):
|
|
|
|
rpm = models.PositiveIntegerField(
|
|
|
|
verbose_name=_('rounds per minute'),
|
|
|
|
choices=[
|
|
|
|
(33, _('33 RPM')),
|
|
|
|
(45, _('45 RPM')),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("vinyl")
|
|
|
|
verbose_name_plural = _("vinyls")
|
|
|
|
ordering = ['title']
|
|
|
|
|
|
|
|
|
|
|
|
class CD(Medium):
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("CD")
|
|
|
|
verbose_name_plural = _("CDs")
|
|
|
|
ordering = ['title']
|
|
|
|
|
|
|
|
|
|
|
|
class Review(Borrowable):
|
|
|
|
number = models.PositiveIntegerField(
|
|
|
|
verbose_name=_('number'),
|
|
|
|
)
|
|
|
|
|
|
|
|
year = models.PositiveIntegerField(
|
|
|
|
verbose_name=_('year'),
|
|
|
|
null=True,
|
|
|
|
blank=True,
|
|
|
|
default=None,
|
|
|
|
)
|
|
|
|
|
|
|
|
month = models.PositiveIntegerField(
|
|
|
|
verbose_name=_('month'),
|
|
|
|
null=True,
|
|
|
|
blank=True,
|
|
|
|
default=None,
|
|
|
|
)
|
|
|
|
|
|
|
|
day = models.PositiveIntegerField(
|
|
|
|
verbose_name=_('day'),
|
|
|
|
null=True,
|
|
|
|
blank=True,
|
|
|
|
default=None,
|
|
|
|
)
|
|
|
|
|
|
|
|
double = models.BooleanField(
|
|
|
|
verbose_name=_('double'),
|
|
|
|
default=False,
|
|
|
|
)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.title + " n°" + str(self.number)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("review")
|
|
|
|
verbose_name_plural = _("reviews")
|
|
|
|
ordering = ['title', 'number']
|
|
|
|
|
|
|
|
|
2021-10-23 16:31:03 +00:00
|
|
|
class FutureMedium(models.Model):
|
2020-05-12 15:33:32 +00:00
|
|
|
isbn = ISBNField(
|
|
|
|
_('ISBN'),
|
|
|
|
help_text=_('You may be able to scan it from a bar code.'),
|
|
|
|
unique=True,
|
|
|
|
blank=True,
|
|
|
|
null=True,
|
|
|
|
)
|
|
|
|
|
2020-05-22 19:37:02 +00:00
|
|
|
type = models.CharField(
|
|
|
|
_('type'),
|
|
|
|
choices=[
|
2021-10-23 16:31:03 +00:00
|
|
|
('bd', _('Comic')),
|
2020-05-22 19:37:02 +00:00
|
|
|
('manga', _('Manga')),
|
|
|
|
('roman', _('Roman')),
|
|
|
|
],
|
|
|
|
max_length=8,
|
|
|
|
)
|
|
|
|
|
2020-09-25 12:20:17 +00:00
|
|
|
present = models.BooleanField(
|
|
|
|
verbose_name=_("present"),
|
|
|
|
help_text=_("Tell that the medium is present in the Mediatek."),
|
|
|
|
default=False,
|
|
|
|
)
|
|
|
|
|
2020-05-12 15:33:32 +00:00
|
|
|
class Meta:
|
|
|
|
verbose_name = _("future medium")
|
|
|
|
verbose_name_plural = _("future media")
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return "Future medium (ISBN: {isbn})".format(isbn=self.isbn, )
|
|
|
|
|
|
|
|
|
2021-11-14 13:26:41 +00:00
|
|
|
class Borrow(models.Model):
|
|
|
|
borrowable = models.ForeignKey(
|
2021-10-26 09:37:32 +00:00
|
|
|
'media.Borrowable',
|
2019-08-16 12:01:13 +00:00
|
|
|
on_delete=models.PROTECT,
|
2021-11-14 13:26:41 +00:00
|
|
|
verbose_name=_('object'),
|
2019-08-16 12:01:13 +00:00
|
|
|
)
|
|
|
|
user = models.ForeignKey(
|
2021-11-14 13:26:41 +00:00
|
|
|
settings.AUTH_USER_MODEL,
|
2019-08-16 12:01:13 +00:00
|
|
|
on_delete=models.PROTECT,
|
|
|
|
verbose_name=_("borrower"),
|
|
|
|
)
|
2021-11-14 13:26:41 +00:00
|
|
|
borrow_date = models.DateTimeField(
|
2019-08-16 12:01:13 +00:00
|
|
|
verbose_name=_('borrowed on'),
|
|
|
|
)
|
2021-11-14 13:26:41 +00:00
|
|
|
given_back = models.DateTimeField(
|
2019-08-08 14:33:05 +00:00
|
|
|
blank=True,
|
|
|
|
null=True,
|
2019-08-16 12:01:13 +00:00
|
|
|
verbose_name=_('given back on'),
|
2019-08-08 14:33:05 +00:00
|
|
|
)
|
2021-11-14 13:26:41 +00:00
|
|
|
borrowed_with = models.ForeignKey(
|
|
|
|
settings.AUTH_USER_MODEL,
|
2019-08-08 14:33:05 +00:00
|
|
|
on_delete=models.PROTECT,
|
2021-11-14 13:26:41 +00:00
|
|
|
related_name='+',
|
2019-08-16 12:01:13 +00:00
|
|
|
verbose_name=_('borrowed with'),
|
|
|
|
help_text=_('The keyholder that registered this borrowed item.')
|
2019-08-08 14:33:05 +00:00
|
|
|
)
|
2021-11-14 13:26:41 +00:00
|
|
|
given_back_to = models.ForeignKey(
|
|
|
|
settings.AUTH_USER_MODEL,
|
2019-08-08 14:33:05 +00:00
|
|
|
on_delete=models.PROTECT,
|
2021-11-14 13:26:41 +00:00
|
|
|
related_name='+',
|
2019-08-08 14:33:05 +00:00
|
|
|
blank=True,
|
|
|
|
null=True,
|
2019-08-16 12:01:13 +00:00
|
|
|
verbose_name=_('given back to'),
|
|
|
|
help_text=_('The keyholder to whom this item was given back.')
|
2019-08-08 14:33:05 +00:00
|
|
|
)
|
2017-07-06 15:30:23 +00:00
|
|
|
|
|
|
|
def __str__(self):
|
2021-11-14 13:26:41 +00:00
|
|
|
return str(self.borrowable) + str(self.user)
|
2019-08-02 12:57:53 +00:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("borrowed item")
|
|
|
|
verbose_name_plural = _("borrowed items")
|
2021-11-14 13:26:41 +00:00
|
|
|
ordering = ['-borrow_date']
|
2019-08-02 12:57:53 +00:00
|
|
|
|
2017-06-30 01:25:07 +00:00
|
|
|
|
2021-10-26 09:37:32 +00:00
|
|
|
class Game(Borrowable):
|
|
|
|
DURATIONS = (
|
|
|
|
('-1h', '-1h'),
|
|
|
|
('1-2h', '1-2h'),
|
|
|
|
('2-3h', '2-3h'),
|
|
|
|
('3-4h', '3-4h'),
|
|
|
|
('4h+', '4h+'),
|
|
|
|
)
|
|
|
|
owner = models.ForeignKey(
|
|
|
|
'users.User',
|
|
|
|
on_delete=models.PROTECT,
|
|
|
|
verbose_name=_("owner"),
|
|
|
|
)
|
|
|
|
duration = models.CharField(
|
|
|
|
choices=DURATIONS,
|
|
|
|
max_length=255,
|
|
|
|
verbose_name=_("duration"),
|
|
|
|
)
|
|
|
|
players_min = models.IntegerField(
|
|
|
|
validators=[MinValueValidator(1)],
|
|
|
|
verbose_name=_("minimum number of players"),
|
|
|
|
)
|
|
|
|
players_max = models.IntegerField(
|
|
|
|
validators=[MinValueValidator(1)],
|
|
|
|
verbose_name=_('maximum number of players'),
|
|
|
|
)
|
|
|
|
comment = models.CharField(
|
|
|
|
max_length=255,
|
|
|
|
blank=True,
|
|
|
|
verbose_name=_('comment'),
|
|
|
|
)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return str(self.title)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("game")
|
|
|
|
verbose_name_plural = _("games")
|
|
|
|
ordering = ['title']
|