1
0
mirror of https://gitlab.crans.org/mediatek/med.git synced 2025-02-25 10:26:32 +00:00

Compare commits

..

No commits in common. "faf697d3cfede753dac956147b851da889792183" and "0b3701f01fed4bb87a23613d7c35b1cd6e5b47ba" have entirely different histories.

14 changed files with 344 additions and 679 deletions

View File

@ -9,8 +9,8 @@ py39-django22:
- > - >
apt-get update && apt-get update &&
apt-get install --no-install-recommends -y apt-get install --no-install-recommends -y
python3-django python3-django-polymorphic python3-django-reversion python3-django python3-django-reversion python3-djangorestframework
python3-djangorestframework python3-docutils python3-requests tox python3-docutils python3-requests tox
script: tox -e py39 script: tox -e py39
linters: linters:

View File

@ -36,7 +36,6 @@ INSTALLED_APPS = [
'reversion', 'reversion',
'rest_framework', 'rest_framework',
'django_extensions', 'django_extensions',
'polymorphic',
# Django contrib # Django contrib
'django.contrib.admin', 'django.contrib.admin',

View File

@ -5,14 +5,12 @@
from django.urls import reverse from django.urls import reverse
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from polymorphic.admin import PolymorphicChildModelAdmin, \
PolymorphicParentModelAdmin
from med.admin import admin_site from med.admin import admin_site
from reversion.admin import VersionAdmin from reversion.admin import VersionAdmin
from .forms import MediaAdminForm from .forms import MediaAdminForm
from .models import Author, Borrowable, CD, Comic, Emprunt, FutureMedium, \ from .models import Author, CD, Comic, Emprunt, FutureMedium, Game, Manga,\
Game, Manga, Novel, Review, Vinyl Novel, Review, Vinyl
class AuthorAdmin(VersionAdmin): class AuthorAdmin(VersionAdmin):
@ -20,17 +18,7 @@ class AuthorAdmin(VersionAdmin):
search_fields = ('name',) search_fields = ('name',)
class BorrowableAdmin(PolymorphicParentModelAdmin): class MediumAdmin(VersionAdmin):
search_fields = ('title',)
child_models = (CD, Comic, Manga, Novel, Review, Vinyl,)
def get_model_perms(self, request):
# We don't want that the borrowable items appear directly in
# main menu, but we still want search borrowable items.
return {}
class MediumAdmin(VersionAdmin, PolymorphicChildModelAdmin):
list_display = ('__str__', 'authors_list', 'side_identifier', 'isbn', list_display = ('__str__', 'authors_list', 'side_identifier', 'isbn',
'external_link') 'external_link')
search_fields = ('title', 'authors__name', 'side_identifier', 'subtitle', search_fields = ('title', 'authors__name', 'side_identifier', 'subtitle',
@ -38,7 +26,6 @@ class MediumAdmin(VersionAdmin, PolymorphicChildModelAdmin):
autocomplete_fields = ('authors',) autocomplete_fields = ('authors',)
date_hierarchy = 'publish_date' date_hierarchy = 'publish_date'
form = MediaAdminForm form = MediaAdminForm
show_in_index = True
def authors_list(self, obj): def authors_list(self, obj):
return ", ".join([a.name for a in obj.authors.all()]) return ", ".join([a.name for a in obj.authors.all()])
@ -90,11 +77,10 @@ class FutureMediumAdmin(VersionAdmin):
extra_context=extra_context) extra_context=extra_context)
class CDAdmin(VersionAdmin, PolymorphicChildModelAdmin): class CDAdmin(VersionAdmin):
list_display = ('title', 'authors_list', 'side_identifier',) list_display = ('title', 'authors_list', 'side_identifier',)
search_fields = ('title', 'authors__name', 'side_identifier',) search_fields = ('title', 'authors__name', 'side_identifier',)
autocomplete_fields = ('authors',) autocomplete_fields = ('authors',)
show_in_index = True
def authors_list(self, obj): def authors_list(self, obj):
return ", ".join([a.name for a in obj.authors.all()]) return ", ".join([a.name for a in obj.authors.all()])
@ -102,11 +88,10 @@ class CDAdmin(VersionAdmin, PolymorphicChildModelAdmin):
authors_list.short_description = _('authors') authors_list.short_description = _('authors')
class VinylAdmin(VersionAdmin, PolymorphicChildModelAdmin): class VinylAdmin(VersionAdmin):
list_display = ('title', 'authors_list', 'side_identifier', 'rpm',) list_display = ('title', 'authors_list', 'side_identifier', 'rpm',)
search_fields = ('title', 'authors__name', 'side_identifier', 'rpm',) search_fields = ('title', 'authors__name', 'side_identifier', 'rpm',)
autocomplete_fields = ('authors',) autocomplete_fields = ('authors',)
show_in_index = True
def authors_list(self, obj): def authors_list(self, obj):
return ", ".join([a.name for a in obj.authors.all()]) return ", ".join([a.name for a in obj.authors.all()])
@ -114,10 +99,9 @@ class VinylAdmin(VersionAdmin, PolymorphicChildModelAdmin):
authors_list.short_description = _('authors') authors_list.short_description = _('authors')
class ReviewAdmin(VersionAdmin, PolymorphicChildModelAdmin): class ReviewAdmin(VersionAdmin):
list_display = ('__str__', 'number', 'year', 'month', 'day', 'double',) list_display = ('__str__', 'number', 'year', 'month', 'day', 'double',)
search_fields = ('title', 'number', 'year',) search_fields = ('title', 'number', 'year',)
show_in_index = True
class EmpruntAdmin(VersionAdmin): class EmpruntAdmin(VersionAdmin):
@ -156,16 +140,14 @@ class EmpruntAdmin(VersionAdmin):
return super().add_view(request, form_url, extra_context) return super().add_view(request, form_url, extra_context)
class GameAdmin(VersionAdmin, PolymorphicChildModelAdmin): class GameAdmin(VersionAdmin):
list_display = ('title', 'owner', 'duration', 'players_min', list_display = ('name', 'owner', 'duration', 'players_min',
'players_max', 'comment') 'players_max', 'comment')
search_fields = ('name', 'owner__username', 'duration', 'comment') search_fields = ('name', 'owner__username', 'duration', 'comment')
autocomplete_fields = ('owner',) autocomplete_fields = ('owner',)
show_in_index = True
admin_site.register(Author, AuthorAdmin) admin_site.register(Author, AuthorAdmin)
admin_site.register(Borrowable, BorrowableAdmin)
admin_site.register(Comic, MediumAdmin) admin_site.register(Comic, MediumAdmin)
admin_site.register(Manga, MediumAdmin) admin_site.register(Manga, MediumAdmin)
admin_site.register(Novel, MediumAdmin) admin_site.register(Novel, MediumAdmin)

View File

@ -9,7 +9,6 @@ import unicodedata
from urllib.error import HTTPError from urllib.error import HTTPError
import urllib.request import urllib.request
from django.core.exceptions import ValidationError
from django.db.models import QuerySet from django.db.models import QuerySet
from django.forms import ModelForm from django.forms import ModelForm
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -321,13 +320,6 @@ class MediaAdminForm(ModelForm):
return self.cleaned_data return self.cleaned_data
def _clean_fields(self): def _clean_fields(self):
# First clean ISBN field
isbn_field = self.fields['isbn']
isbn = isbn_field.widget.value_from_datadict(
self.data, self.files, self.add_prefix('isbn'))
isbn = isbn_field.clean(isbn)
self.cleaned_data['isbn'] = isbn
for name, field in self.fields.items(): for name, field in self.fields.items():
# value_from_datadict() gets the data from the data dictionaries. # value_from_datadict() gets the data from the data dictionaries.
# Each widget type knows how to retrieve its own data, because some # Each widget type knows how to retrieve its own data, because some
@ -337,6 +329,7 @@ class MediaAdminForm(ModelForm):
else: else:
value = field.widget.value_from_datadict( value = field.widget.value_from_datadict(
self.data, self.files, self.add_prefix(name)) self.data, self.files, self.add_prefix(name))
from django.core.exceptions import ValidationError
try: try:
# We don't want to check a field when we enter an ISBN. # We don't want to check a field when we enter an ISBN.
if "isbn" not in self.data \ if "isbn" not in self.data \

View File

@ -3,7 +3,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-10-26 15:14+0200\n" "POT-Creation-Date: 2021-10-23 18:27+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -13,20 +13,20 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: admin.py:46 admin.py:102 admin.py:114 models.py:30 models.py:77 #: admin.py:33 admin.py:88 admin.py:99 models.py:29 models.py:65 models.py:130
#: models.py:149 models.py:221 models.py:290 models.py:348 models.py:394 #: models.py:192 models.py:243 models.py:274
msgid "authors" msgid "authors"
msgstr "auteurs" msgstr "auteurs"
#: admin.py:56 #: admin.py:43
msgid "external url" msgid "external url"
msgstr "URL externe" msgstr "URL externe"
#: admin.py:142 #: admin.py:126
msgid "Turn back" msgid "Turn back"
msgstr "Rendre" msgstr "Rendre"
#: admin.py:145 models.py:574 #: admin.py:129 models.py:407
msgid "given back to" msgid "given back to"
msgstr "rendu à" msgstr "rendu à"
@ -38,250 +38,221 @@ msgstr "ISBN-10 ou ISBN-13"
msgid "This ISBN is not found." msgid "This ISBN is not found."
msgstr "L'ISBN n'a pas été trouvé." msgstr "L'ISBN n'a pas été trouvé."
#: management/commands/migrate_to_new_format.py:52 models.py:408 models.py:415 #: models.py:16 models.py:431
msgid "CDs"
msgstr "CDs"
#: management/commands/migrate_to_new_format.py:52 models.py:407 models.py:414
msgid "CD"
msgstr "CD"
#: management/commands/migrate_to_new_format.py:68 models.py:362 models.py:377
msgid "vinyls"
msgstr "vinyles"
#: management/commands/migrate_to_new_format.py:68 models.py:361 models.py:376
msgid "vinyl"
msgstr "vinyle"
#: management/commands/migrate_to_new_format.py:86 models.py:466 models.py:506
msgid "reviews"
msgstr "revues"
#: management/commands/migrate_to_new_format.py:86 models.py:465 models.py:505
msgid "review"
msgstr "revue"
#: management/commands/migrate_to_new_format.py:106 models.py:629 models.py:670
msgid "games"
msgstr "jeux"
#: management/commands/migrate_to_new_format.py:106 models.py:628 models.py:669
msgid "game"
msgstr "jeu"
#: models.py:17 models.py:598
msgid "name" msgid "name"
msgstr "nom" msgstr "nom"
#: models.py:22 #: models.py:21
msgid "note" msgid "note"
msgstr "note" msgstr "note"
#: models.py:29 #: models.py:28
msgid "author" msgid "author"
msgstr "auteur" msgstr "auteur"
#: models.py:37 models.py:127 models.py:199 models.py:268 models.py:329 #: models.py:35 models.py:100 models.py:162 models.py:345
#: models.py:383 models.py:421
msgid "title"
msgstr "titre"
#: models.py:41 models.py:165 models.py:237 models.py:306 models.py:352
#: models.py:398 models.py:456 models.py:530
msgid "present"
msgstr "présent"
#: models.py:42 models.py:166 models.py:238 models.py:307 models.py:353
#: models.py:399 models.py:457 models.py:531
msgid "Tell that the medium is present in the Mediatek."
msgstr "Indique que le medium est présent à la Mediatek."
#: models.py:60
msgid "borrowable"
msgstr "empruntable"
#: models.py:61
msgid "borrowables"
msgstr "empruntables"
#: models.py:66 models.py:138 models.py:210 models.py:279
msgid "external URL"
msgstr "URL externe"
#: models.py:71 models.py:143 models.py:215 models.py:284 models.py:334
#: models.py:388
msgid "side identifier"
msgstr "côte"
#: models.py:81
msgid "medium"
msgstr "medium"
#: models.py:82
msgid "media"
msgstr "media"
#: models.py:87 models.py:119 models.py:191 models.py:260 models.py:512
msgid "ISBN" msgid "ISBN"
msgstr "ISBN" msgstr "ISBN"
#: models.py:88 models.py:120 models.py:192 models.py:261 models.py:513 #: models.py:36 models.py:101 models.py:163 models.py:346
msgid "You may be able to scan it from a bar code." msgid "You may be able to scan it from a bar code."
msgstr "Peut souvent être scanné à partir du code barre." msgstr "Peut souvent être scanné à partir du code barre."
#: models.py:95 models.py:132 models.py:204 models.py:273 #: models.py:43 models.py:108 models.py:170 models.py:224 models.py:263
#: models.py:294
msgid "title"
msgstr "titre"
#: models.py:48 models.py:113 models.py:175
msgid "subtitle" msgid "subtitle"
msgstr "sous-titre" msgstr "sous-titre"
#: models.py:101 models.py:153 models.py:225 models.py:294 #: models.py:54 models.py:119 models.py:181
msgid "external URL"
msgstr "URL externe"
#: models.py:59 models.py:124 models.py:186 models.py:229 models.py:268
msgid "side identifier"
msgstr "côte"
#: models.py:69 models.py:134 models.py:196
msgid "number of pages" msgid "number of pages"
msgstr "nombre de pages" msgstr "nombre de pages"
#: models.py:107 models.py:159 models.py:231 models.py:300 #: models.py:75 models.py:140 models.py:202
msgid "publish date" msgid "publish date"
msgstr "date de publication" msgstr "date de publication"
#: models.py:113 #: models.py:81 models.py:146 models.py:208 models.py:247 models.py:278
msgid "book" #: models.py:329 models.py:363
msgstr "livre" msgid "present"
msgstr "présent"
#: models.py:114 #: models.py:82 models.py:147 models.py:209 models.py:248 models.py:279
msgid "books" #: models.py:330 models.py:364
msgstr "livres" msgid "Tell that the medium is present in the Mediatek."
msgstr "Indique que le medium est présent à la Mediatek."
#: models.py:177 models.py:184 #: models.py:93 models.py:355
msgid "comic" msgid "comic"
msgstr "BD" msgstr "BD"
#: models.py:178 models.py:185 #: models.py:94
msgid "comics" msgid "comics"
msgstr "BDs" msgstr "BDs"
#: models.py:246 models.py:253 #: models.py:155
msgid "manga" msgid "manga"
msgstr "manga" msgstr "manga"
#: models.py:247 models.py:254 #: models.py:156
msgid "mangas" msgid "mangas"
msgstr "mangas" msgstr "mangas"
#: models.py:315 models.py:322 #: models.py:217
msgid "novel" msgid "novel"
msgstr "roman" msgstr "roman"
#: models.py:316 models.py:323 #: models.py:218
msgid "novels" msgid "novels"
msgstr "romans" msgstr "romans"
#: models.py:339 models.py:368 #: models.py:234
msgid "rounds per minute" msgid "rounds per minute"
msgstr "tours par minute" msgstr "tours par minute"
#: models.py:341 models.py:370 #: models.py:236
msgid "33 RPM" msgid "33 RPM"
msgstr "33 TPM" msgstr "33 TPM"
#: models.py:342 models.py:371 #: models.py:237
msgid "45 RPM" msgid "45 RPM"
msgstr "45 TPM" msgstr "45 TPM"
#: models.py:426 models.py:472 #: models.py:256
msgid "vinyl"
msgstr "vinyle"
#: models.py:257
msgid "vinyls"
msgstr "vinyles"
#: models.py:287
msgid "CD"
msgstr "CD"
#: models.py:288
msgid "CDs"
msgstr "CDs"
#: models.py:299
msgid "number" msgid "number"
msgstr "nombre" msgstr "nombre"
#: models.py:430 models.py:476 #: models.py:303
msgid "year" msgid "year"
msgstr "année" msgstr "année"
#: models.py:437 models.py:483 #: models.py:310
msgid "month" msgid "month"
msgstr "mois" msgstr "mois"
#: models.py:444 models.py:490 #: models.py:317
msgid "day" msgid "day"
msgstr "jour" msgstr "jour"
#: models.py:451 models.py:497 #: models.py:324
msgid "double" msgid "double"
msgstr "double" msgstr "double"
#: models.py:520 #: models.py:338
msgid "review"
msgstr "revue"
#: models.py:339
msgid "reviews"
msgstr "revues"
#: models.py:353
msgid "type" msgid "type"
msgstr "type" msgstr "type"
#: models.py:522 #: models.py:356
msgid "Comic"
msgstr "BD"
#: models.py:523
msgid "Manga" msgid "Manga"
msgstr "Manga" msgstr "Manga"
#: models.py:524 #: models.py:357
msgid "Roman" msgid "Roman"
msgstr "Roman" msgstr "Roman"
#: models.py:536 #: models.py:369
msgid "future medium" msgid "future medium"
msgstr "medium à importer" msgstr "medium à importer"
#: models.py:537 #: models.py:370
msgid "future media" msgid "future media"
msgstr "medias à importer" msgstr "medias à importer"
#: models.py:551 #: models.py:384
msgid "borrower" msgid "borrower"
msgstr "emprunteur" msgstr "emprunteur"
#: models.py:554 #: models.py:387
msgid "borrowed on" msgid "borrowed on"
msgstr "emprunté le" msgstr "emprunté le"
#: models.py:559 #: models.py:392
msgid "given back on" msgid "given back on"
msgstr "rendu le" msgstr "rendu le"
#: models.py:565 #: models.py:398
msgid "borrowed with" msgid "borrowed with"
msgstr "emprunté avec" msgstr "emprunté avec"
#: models.py:566 #: models.py:399
msgid "The keyholder that registered this borrowed item." msgid "The keyholder that registered this borrowed item."
msgstr "Le permanencier qui enregistre cet emprunt." msgstr "Le permanencier qui enregistre cet emprunt."
#: models.py:575 #: models.py:408
msgid "The keyholder to whom this item was given back." msgid "The keyholder to whom this item was given back."
msgstr "Le permanencier à qui l'emprunt a été rendu." msgstr "Le permanencier à qui l'emprunt a été rendu."
#: models.py:582 #: models.py:415
msgid "borrowed item" msgid "borrowed item"
msgstr "emprunt" msgstr "emprunt"
#: models.py:583 #: models.py:416
msgid "borrowed items" msgid "borrowed items"
msgstr "emprunts" msgstr "emprunts"
#: models.py:603 models.py:644 #: models.py:436
msgid "owner" msgid "owner"
msgstr "propriétaire" msgstr "propriétaire"
#: models.py:608 models.py:649 #: models.py:441
msgid "duration" msgid "duration"
msgstr "durée" msgstr "durée"
#: models.py:612 models.py:653 #: models.py:445
msgid "minimum number of players" msgid "minimum number of players"
msgstr "nombre minimum de joueurs" msgstr "nombre minimum de joueurs"
#: models.py:616 models.py:657 #: models.py:449
msgid "maximum number of players" msgid "maximum number of players"
msgstr "nombre maximum de joueurs" msgstr "nombre maximum de joueurs"
#: models.py:621 models.py:662 #: models.py:454
msgid "comment" msgid "comment"
msgstr "commentaire" msgstr "commentaire"
#: models.py:461
msgid "game"
msgstr "jeu"
#: models.py:462
msgid "games"
msgstr "jeux"
#: templates/media/generate_side_identifier.html:3 #: templates/media/generate_side_identifier.html:3
msgid "Generate side identifier" msgid "Generate side identifier"
msgstr "Générer la cote" msgstr "Générer la cote"
@ -306,6 +277,6 @@ msgstr "ISBN invalide : mauvaise longueur"
msgid "Invalid ISBN: Only upper case allowed" msgid "Invalid ISBN: Only upper case allowed"
msgstr "ISBN invalide : seulement les majuscules sont autorisées" msgstr "ISBN invalide : seulement les majuscules sont autorisées"
#: views.py:47 #: views.py:51
msgid "Welcome to the Mediatek database" msgid "Welcome to the Mediatek database"
msgstr "Bienvenue sur la base de données de la Mediatek" msgstr "Bienvenue sur la base de données de la Mediatek"

View File

@ -1,133 +0,0 @@
from django.core.management import BaseCommand
from django.db import transaction
from django.utils.translation import gettext_lazy as _
from media.models import CD, Comic, Game, Manga, Novel, Review, Vinyl
from tqdm import tqdm
class Command(BaseCommand):
"""
Convert old format into new format
"""
def add_arguments(self, parser):
parser.add_argument('--doit', action='store_true',
help="Actually do the mogration.")
@transaction.atomic
def handle(self, *args, **options): # noqa: C901
self.stderr.write(self.style.WARNING(
"Old data structure has been deleted. This script won't work "
"anymore (and is now useless)"))
from media.models import OldCD, OldComic, OldGame, OldManga, OldNovel, \
OldReview, OldVinyl
# Migrate books
for old_book_class, book_class in [(OldComic, Comic),
(OldManga, Manga),
(OldNovel, Novel)]:
name = book_class._meta.verbose_name
name_plural = book_class._meta.verbose_name_plural
for book in tqdm(old_book_class.objects.all(),
desc=name_plural, unit=str(name)):
try:
new_book = book_class.objects.create(
isbn=book.isbn,
title=book.title,
subtitle=book.subtitle,
external_url=book.external_url,
side_identifier=book.side_identifier,
number_of_pages=book.number_of_pages,
publish_date=book.publish_date,
present=book.present,
)
new_book.authors.set(book.authors.all())
new_book.save()
except Exception:
self.stderr.write(f"There was an error with {name} "
f"{book} ({book.pk})")
raise
self.stdout.write(f"{book_class.objects.count()} {name_plural} "
"migrated")
# Migrate CDs
for cd in tqdm(OldCD.objects.all(),
desc=_("CDs"), unit=str(_("CD"))):
try:
new_cd = CD.objects.create(
title=cd.title,
present=cd.present,
)
new_cd.authors.set(cd.authors.all())
new_cd.save()
except Exception:
self.stderr.write(f"There was an error with {cd} ({cd.pk})")
raise
self.stdout.write(f"{CD.objects.count()} {_('CDs')} migrated")
# Migrate vinyls
for vinyl in tqdm(OldVinyl.objects.all(),
desc=_("vinyls"), unit=str(_("vinyl"))):
try:
new_vinyl = Vinyl.objects.create(
title=vinyl.title,
present=vinyl.present,
rpm=vinyl.rpm,
)
new_vinyl.authors.set(vinyl.authors.all())
new_vinyl.save()
except Exception:
self.stderr.write(f"There was an error with {vinyl} "
f"({vinyl.pk})")
raise
self.stdout.write(f"{Vinyl.objects.count()} {_('vinyls')} migrated")
# Migrate reviews
for review in tqdm(OldReview.objects.all(),
desc=_("reviews"), unit=str(_("review"))):
try:
Review.objects.create(
title=review.title,
number=review.number,
year=review.year,
month=review.month,
day=review.day,
double=review.double,
present=review.present,
)
except Exception:
self.stderr.write(f"There was an error with {review} "
f"({review.pk})")
raise
self.stdout.write(f"{Review.objects.count()} {_('reviews')} migrated")
# Migrate games
for game in tqdm(OldGame.objects.all(),
desc=_("games"), unit=str(_("game"))):
try:
Game.objects.create(
title=game.title,
owner=game.owner,
duration=game.duration,
players_min=game.players_min,
players_max=game.players_max,
comment=game.comment,
)
except Exception:
self.stderr.write(f"There was an error with {game} "
f"({game.pk})")
raise
self.stdout.write(f"{Game.objects.count()} {_('games')} migrated")
if not options['doit']:
self.stdout.write(self.style.WARNING(
"Warning: Data were't saved. Please use --doit option "
"to really perform the migration."
))
exit(1)

View File

@ -1,70 +0,0 @@
# Generated by Django 2.2.17 on 2021-10-23 17:29
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('media', '0041_auto_20211023_1838'),
]
operations = [
migrations.RenameModel(
old_name='CD',
new_name='OldCD',
),
migrations.RenameModel(
old_name='Manga',
new_name='OldManga',
),
# Remove index before renaming the model
migrations.AlterField(
model_name='game',
name='owner',
field=models.ForeignKey(db_index=False, on_delete=models.deletion.PROTECT, to=settings.AUTH_USER_MODEL, verbose_name='owner'),
),
migrations.RenameModel(
old_name='Game',
new_name='OldGame',
),
migrations.AlterField(
model_name='oldgame',
name='owner',
field=models.ForeignKey(db_index=True, on_delete=models.deletion.PROTECT, to=settings.AUTH_USER_MODEL, verbose_name='owner'),
),
migrations.RenameField(
model_name='oldgame',
old_name='name',
new_name='title',
),
migrations.RenameModel(
old_name='Novel',
new_name='OldNovel',
),
migrations.RenameModel(
old_name='Comic',
new_name='OldComic',
),
migrations.RenameModel(
old_name='Review',
new_name='OldReview',
),
migrations.RenameModel(
old_name='Vinyl',
new_name='OldVinyl',
),
migrations.AlterModelOptions(
name='oldcomic',
options={'ordering': ['title', 'subtitle'], 'verbose_name': 'comic', 'verbose_name_plural': 'comics'},
),
migrations.AlterModelOptions(
name='oldmanga',
options={'ordering': ['title'], 'verbose_name': 'manga', 'verbose_name_plural': 'mangas'},
),
migrations.AlterModelOptions(
name='oldnovel',
options={'ordering': ['title', 'subtitle'], 'verbose_name': 'novel', 'verbose_name_plural': 'novels'},
),
]

View File

@ -1,166 +0,0 @@
# Generated by Django 2.2.17 on 2021-10-23 18:12
from django.conf import settings
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import media.fields
import media.validators
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('media', '0042_auto_20211023_1929'),
]
operations = [
migrations.CreateModel(
name='Borrowable',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('isbn', media.fields.ISBNField(blank=True, help_text='You may be able to scan it from a bar code.', max_length=28, null=True, unique=True, validators=[media.validators.isbn_validator], verbose_name='ISBN')),
('title', models.CharField(max_length=255, verbose_name='title')),
('present', models.BooleanField(default=False, help_text='Tell that the medium is present in the Mediatek.', verbose_name='present')),
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_media.borrowable_set+', to='contenttypes.ContentType')),
],
options={
'verbose_name': 'borrowable',
'verbose_name_plural': 'borrowables',
},
),
migrations.AlterModelOptions(
name='oldgame',
options={'ordering': ['title'], 'verbose_name': 'game', 'verbose_name_plural': 'games'},
),
migrations.AlterField(
model_name='emprunt',
name='media',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='media.Borrowable'),
),
migrations.CreateModel(
name='Medium',
fields=[
('borrowable_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='media.Borrowable')),
('external_url', models.URLField(blank=True, verbose_name='external URL')),
('side_identifier', models.CharField(max_length=255, verbose_name='side identifier')),
('authors', models.ManyToManyField(to='media.Author', verbose_name='authors')),
],
options={
'verbose_name': 'medium',
'verbose_name_plural': 'media',
},
bases=('media.borrowable',),
),
migrations.CreateModel(
name='Review',
fields=[
('borrowable_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='media.Borrowable')),
('number', models.PositiveIntegerField(verbose_name='number')),
('year', models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='year')),
('month', models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='month')),
('day', models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='day')),
('double', models.BooleanField(default=False, verbose_name='double')),
],
options={
'verbose_name': 'review',
'verbose_name_plural': 'reviews',
'ordering': ['title', 'number'],
},
bases=('media.borrowable',),
),
migrations.CreateModel(
name='Book',
fields=[
('medium_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='media.Medium')),
('subtitle', models.CharField(blank=True, max_length=255, verbose_name='subtitle')),
('number_of_pages', models.PositiveIntegerField(blank=True, null=True, verbose_name='number of pages')),
('publish_date', models.DateField(blank=True, null=True, verbose_name='publish date')),
],
options={
'verbose_name': 'book',
'verbose_name_plural': 'books',
},
bases=('media.medium',),
),
migrations.CreateModel(
name='CD',
fields=[
('medium_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='media.Medium')),
],
options={
'verbose_name': 'CD',
'verbose_name_plural': 'CDs',
'ordering': ['title'],
},
bases=('media.medium',),
),
migrations.CreateModel(
name='Vinyl',
fields=[
('medium_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='media.Medium')),
('rpm', models.PositiveIntegerField(choices=[(33, '33 RPM'), (45, '45 RPM')], verbose_name='rounds per minute')),
],
options={
'verbose_name': 'vinyl',
'verbose_name_plural': 'vinyls',
'ordering': ['title'],
},
bases=('media.medium',),
),
migrations.CreateModel(
name='Game',
fields=[
('borrowable_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='media.Borrowable')),
('duration', models.CharField(choices=[('-1h', '-1h'), ('1-2h', '1-2h'), ('2-3h', '2-3h'), ('3-4h', '3-4h'), ('4h+', '4h+')], max_length=255, verbose_name='duration')),
('players_min', models.IntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='minimum number of players')),
('players_max', models.IntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='maximum number of players')),
('comment', models.CharField(blank=True, max_length=255, verbose_name='comment')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL, verbose_name='owner')),
],
options={
'verbose_name': 'game',
'verbose_name_plural': 'games',
'ordering': ['title'],
},
bases=('media.borrowable',),
),
migrations.CreateModel(
name='Comic',
fields=[
('book_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='media.Book')),
],
options={
'verbose_name': 'comic',
'verbose_name_plural': 'comics',
'ordering': ['title', 'subtitle'],
},
bases=('media.book',),
),
migrations.CreateModel(
name='Manga',
fields=[
('book_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='media.Book')),
],
options={
'verbose_name': 'manga',
'verbose_name_plural': 'mangas',
'ordering': ['title', 'subtitle'],
},
bases=('media.book',),
),
migrations.CreateModel(
name='Novel',
fields=[
('book_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='media.Book')),
],
options={
'verbose_name': 'novel',
'verbose_name_plural': 'novels',
'ordering': ['title', 'subtitle'],
},
bases=('media.book',),
),
]

View File

@ -1,58 +0,0 @@
# Generated by Django 2.2.24 on 2021-11-02 11:54
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('media', '0043_auto_20211023_2012'),
]
operations = [
migrations.RemoveField(
model_name='oldcd',
name='authors',
),
migrations.RemoveField(
model_name='oldcomic',
name='authors',
),
migrations.RemoveField(
model_name='oldgame',
name='owner',
),
migrations.RemoveField(
model_name='oldmanga',
name='authors',
),
migrations.RemoveField(
model_name='oldnovel',
name='authors',
),
migrations.DeleteModel(
name='OldReview',
),
migrations.RemoveField(
model_name='oldvinyl',
name='authors',
),
migrations.DeleteModel(
name='OldCD',
),
migrations.DeleteModel(
name='OldComic',
),
migrations.DeleteModel(
name='OldGame',
),
migrations.DeleteModel(
name='OldManga',
),
migrations.DeleteModel(
name='OldNovel',
),
migrations.DeleteModel(
name='OldVinyl',
),
]

View File

@ -5,7 +5,6 @@
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from polymorphic.models import PolymorphicModel
from .fields import ISBNField from .fields import ISBNField
@ -31,7 +30,7 @@ class Author(models.Model):
ordering = ['name'] ordering = ['name']
class Borrowable(PolymorphicModel): class Comic(models.Model):
isbn = ISBNField( isbn = ISBNField(
_('ISBN'), _('ISBN'),
help_text=_('You may be able to scan it from a bar code.'), help_text=_('You may be able to scan it from a bar code.'),
@ -41,35 +40,16 @@ class Borrowable(PolymorphicModel):
) )
title = models.CharField( title = models.CharField(
verbose_name=_('title'),
max_length=255, max_length=255,
verbose_name=_("title"),
) )
present = models.BooleanField( subtitle = models.CharField(
verbose_name=_("present"), verbose_name=_('subtitle'),
help_text=_("Tell that the medium is present in the Mediatek."), max_length=255,
default=False, blank=True,
) )
def __str__(self):
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
class Meta:
verbose_name = _('borrowable')
verbose_name_plural = _('borrowables')
class Medium(Borrowable):
external_url = models.URLField( external_url = models.URLField(
verbose_name=_('external URL'), verbose_name=_('external URL'),
blank=True, blank=True,
@ -85,18 +65,71 @@ class Medium(Borrowable):
verbose_name=_('authors'), verbose_name=_('authors'),
) )
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,
)
present = models.BooleanField(
verbose_name=_("present"),
help_text=_("Tell that the medium is present in the Mediatek."),
default=False,
)
def __str__(self):
if self.subtitle:
return "{} : {}".format(self.title, self.subtitle)
else:
return self.title
class Meta: class Meta:
verbose_name = _("medium") verbose_name = _("comic")
verbose_name_plural = _("media") verbose_name_plural = _("comics")
ordering = ['title', 'subtitle']
class Book(Medium): class Manga(models.Model):
isbn = ISBNField(
_('ISBN'),
help_text=_('You may be able to scan it from a bar code.'),
unique=True,
blank=True,
null=True,
)
title = models.CharField(
verbose_name=_('title'),
max_length=255,
)
subtitle = models.CharField( subtitle = models.CharField(
verbose_name=_('subtitle'), verbose_name=_('subtitle'),
max_length=255, max_length=255,
blank=True, blank=True,
) )
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'),
)
number_of_pages = models.PositiveIntegerField( number_of_pages = models.PositiveIntegerField(
verbose_name=_('number of pages'), verbose_name=_('number of pages'),
blank=True, blank=True,
@ -109,33 +142,94 @@ class Book(Medium):
null=True, null=True,
) )
class Meta: present = models.BooleanField(
verbose_name = _("book") verbose_name=_("present"),
verbose_name_plural = _("books") help_text=_("Tell that the medium is present in the Mediatek."),
default=False,
)
def __str__(self):
return self.title
class Comic(Book):
class Meta:
verbose_name = _("comic")
verbose_name_plural = _("comics")
ordering = ['title', 'subtitle']
class Manga(Book):
class Meta: class Meta:
verbose_name = _("manga") verbose_name = _("manga")
verbose_name_plural = _("mangas") verbose_name_plural = _("mangas")
ordering = ['title', 'subtitle'] ordering = ['title']
class Novel(Book): class Novel(models.Model):
isbn = ISBNField(
_('ISBN'),
help_text=_('You may be able to scan it from a bar code.'),
unique=True,
blank=True,
null=True,
)
title = models.CharField(
verbose_name=_('title'),
max_length=255,
)
subtitle = models.CharField(
verbose_name=_('subtitle'),
max_length=255,
blank=True,
)
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'),
)
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,
)
present = models.BooleanField(
verbose_name=_("present"),
help_text=_("Tell that the medium is present in the Mediatek."),
default=False,
)
def __str__(self):
return self.title
class Meta: class Meta:
verbose_name = _("novel") verbose_name = _("novel")
verbose_name_plural = _("novels") verbose_name_plural = _("novels")
ordering = ['title', 'subtitle'] ordering = ['title', 'subtitle']
class Vinyl(Medium): class Vinyl(models.Model):
title = models.CharField(
verbose_name=_('title'),
max_length=255,
)
side_identifier = models.CharField(
verbose_name=_('side identifier'),
max_length=255,
)
rpm = models.PositiveIntegerField( rpm = models.PositiveIntegerField(
verbose_name=_('rounds per minute'), verbose_name=_('rounds per minute'),
choices=[ choices=[
@ -144,20 +238,63 @@ class Vinyl(Medium):
], ],
) )
authors = models.ManyToManyField(
'Author',
verbose_name=_('authors'),
)
present = models.BooleanField(
verbose_name=_("present"),
help_text=_("Tell that the medium is present in the Mediatek."),
default=False,
)
def __str__(self):
return self.title
class Meta: class Meta:
verbose_name = _("vinyl") verbose_name = _("vinyl")
verbose_name_plural = _("vinyls") verbose_name_plural = _("vinyls")
ordering = ['title'] ordering = ['title']
class CD(Medium): class CD(models.Model):
title = models.CharField(
verbose_name=_('title'),
max_length=255,
)
side_identifier = models.CharField(
verbose_name=_('side identifier'),
max_length=255,
)
authors = models.ManyToManyField(
'Author',
verbose_name=_('authors'),
)
present = models.BooleanField(
verbose_name=_("present"),
help_text=_("Tell that the medium is present in the Mediatek."),
default=False,
)
def __str__(self):
return self.title
class Meta: class Meta:
verbose_name = _("CD") verbose_name = _("CD")
verbose_name_plural = _("CDs") verbose_name_plural = _("CDs")
ordering = ['title'] ordering = ['title']
class Review(Borrowable): class Review(models.Model):
title = models.CharField(
verbose_name=_('title'),
max_length=255,
)
number = models.PositiveIntegerField( number = models.PositiveIntegerField(
verbose_name=_('number'), verbose_name=_('number'),
) )
@ -188,6 +325,12 @@ class Review(Borrowable):
default=False, default=False,
) )
present = models.BooleanField(
verbose_name=_("present"),
help_text=_("Tell that the medium is present in the Mediatek."),
default=False,
)
def __str__(self): def __str__(self):
return self.title + "" + str(self.number) return self.title + "" + str(self.number)
@ -232,7 +375,7 @@ class FutureMedium(models.Model):
class Emprunt(models.Model): class Emprunt(models.Model):
media = models.ForeignKey( media = models.ForeignKey(
'media.Borrowable', 'Comic',
on_delete=models.PROTECT, on_delete=models.PROTECT,
) )
user = models.ForeignKey( user = models.ForeignKey(
@ -274,7 +417,7 @@ class Emprunt(models.Model):
ordering = ['-date_emprunt'] ordering = ['-date_emprunt']
class Game(Borrowable): class Game(models.Model):
DURATIONS = ( DURATIONS = (
('-1h', '-1h'), ('-1h', '-1h'),
('1-2h', '1-2h'), ('1-2h', '1-2h'),
@ -282,6 +425,11 @@ class Game(Borrowable):
('3-4h', '3-4h'), ('3-4h', '3-4h'),
('4h+', '4h+'), ('4h+', '4h+'),
) )
name = models.CharField(
max_length=255,
verbose_name=_("name"),
)
owner = models.ForeignKey( owner = models.ForeignKey(
'users.User', 'users.User',
on_delete=models.PROTECT, on_delete=models.PROTECT,
@ -307,9 +455,9 @@ class Game(Borrowable):
) )
def __str__(self): def __str__(self):
return str(self.title) return str(self.name)
class Meta: class Meta:
verbose_name = _("game") verbose_name = _("game")
verbose_name_plural = _("games") verbose_name_plural = _("games")
ordering = ['title'] ordering = ['name']

View File

@ -36,22 +36,22 @@
document.getElementById("isbn").focus(); document.getElementById("isbn").focus();
let bd_request = new XMLHttpRequest(); let bd_request = new XMLHttpRequest();
bd_request.open('GET', '/api/media/comic/?search=' + isbn, true); bd_request.open('GET', '/api/media/bd/?search=' + isbn, true);
bd_request.onload = function () { bd_request.onload = function () {
let data = JSON.parse(this.response); let data = JSON.parse(this.response);
data.results.forEach(comic => { data.results.forEach(bd => {
let present = comic.present; let present = bd.present;
if (markAsPresent && isbn === comic.isbn) { if (markAsPresent && isbn === bd.isbn) {
present = true; present = true;
let presentRequest = new XMLHttpRequest(); let presentRequest = new XMLHttpRequest();
presentRequest.open("GET", "/media/mark-as-present/bd/" + comic.id + "/", true); presentRequest.open("GET", "/media/mark-as-present/bd/" + bd.id + "/", true);
presentRequest.send(); presentRequest.send();
} }
result_div.innerHTML += "<li id='comic_" + comic.id + "'>" + result_div.innerHTML += "<li id='bd_" + bd.id + "'>" +
"<a href='/database/media/comic/" + comic.id + "/change/'>BD : " "<a href='/database/media/bd/" + bd.id + "/change/'>BD : "
+ comic.title + (comic.subtitle ? " - " + comic.subtitle : "") + "</a>" + bd.title + (bd.subtitle ? " - " + bd.subtitle : "") + "</a>"
+ (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('bd', " + comic.id + ", false)\">marquer comme absent</a>)" + (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('bd', " + bd.id + ", false)\">marquer comme absent</a>)"
: " (absent, <a class='present' href='#' onclick=\"markAsPresent('bd', " + comic.id + ")\">marquer comme présent</a>)") + "</li>"; : " (absent, <a class='present' href='#' onclick=\"markAsPresent('bd', " + bd.id + ")\">marquer comme présent</a>)") + "</li>";
}); });
} }
bd_request.send(); bd_request.send();
@ -92,35 +92,35 @@
cd_request.send(); cd_request.send();
let vinyle_request = new XMLHttpRequest(); let vinyle_request = new XMLHttpRequest();
vinyle_request.open('GET', '/api/media/vinyl/?search=' + isbn, true); vinyle_request.open('GET', '/api/media/vinyle/?search=' + isbn, true);
vinyle_request.onload = function () { vinyle_request.onload = function () {
let data = JSON.parse(this.response); let data = JSON.parse(this.response);
data.results.forEach(vinyl => { data.results.forEach(vinyle => {
let present = markAsPresent || vinyl.present; let present = markAsPresent || vinyle.present;
result_div.innerHTML += "<li id='vinyl_" + vinyl.id + "'>" + result_div.innerHTML += "<li id='vinyle_" + vinyle.id + "'>" +
"<a href='/database/media/vinyl/" + vinyl.id + "/change/'>Vinyle : " + vinyl.title + "</a>" "<a href='/database/media/vinyle/" + vinyle.id + "/change/'>Vinyle : " + vinyle.title + "</a>"
+ (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('vinyl', " + vinyl.id + ", false)\">marquer comme absent</a>)" + (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('vinyle', " + vinyle.id + ", false)\">marquer comme absent</a>)"
: " (absent, <a class='present' href='#' onclick=\"markAsPresent('vinyl', " + vinyl.id + ")\">marquer comme présent</a>)") + "</li>"; : " (absent, <a class='present' href='#' onclick=\"markAsPresent('vinyle', " + vinyle.id + ")\">marquer comme présent</a>)") + "</li>";
}); });
} }
vinyle_request.send(); vinyle_request.send();
let roman_request = new XMLHttpRequest(); let roman_request = new XMLHttpRequest();
roman_request.open('GET', '/api/media/novel/?search=' + isbn, true); roman_request.open('GET', '/api/media/roman/?search=' + isbn, true);
roman_request.onload = function () { roman_request.onload = function () {
let data = JSON.parse(this.response); let data = JSON.parse(this.response);
data.results.forEach(novel => { data.results.forEach(roman => {
let present = novel.present; let present = roman.present;
if (markAsPresent && isbn === novel.isbn) { if (markAsPresent && isbn === roman.isbn) {
present = true; present = true;
let presentRequest = new XMLHttpRequest(); let presentRequest = new XMLHttpRequest();
presentRequest.open("GET", "/media/mark-as-present/novel/" + novel.id + "/", true); presentRequest.open("GET", "/media/mark-as-present/roman/" + roman.id + "/", true);
presentRequest.send(); presentRequest.send();
} }
result_div.innerHTML += "<li id='roman_" + novel.id + "'>" + result_div.innerHTML += "<li id='roman_" + roman.id + "'>" +
"<a href='/database/media/roman/" + novel.id + "/change/'>Roman : " + novel.title + "</a>" "<a href='/database/media/roman/" + roman.id + "/change/'>Roman : " + roman.title + "</a>"
+ (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('novel', " + novel.id + ", false)\">marquer comme absent</a>)" + (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('roman', " + roman.id + ", false)\">marquer comme absent</a>)"
: " (absent, <a class='present' href='#' onclick=\"markAsPresent('novel', " + novel.id + ")\">marquer comme présent</a>)") + "</li>"; : " (absent, <a class='present' href='#' onclick=\"markAsPresent('roman', " + roman.id + ")\">marquer comme présent</a>)") + "</li>";
}); });
} }
roman_request.send(); roman_request.send();

View File

@ -12,7 +12,7 @@ urlpatterns = [
url(r'^retour_emprunt/(?P<empruntid>[0-9]+)$', views.retour_emprunt, url(r'^retour_emprunt/(?P<empruntid>[0-9]+)$', views.retour_emprunt,
name='retour-emprunt'), name='retour-emprunt'),
path('find/', views.FindMediumView.as_view(), name="find"), path('find/', views.FindMediumView.as_view(), name="find"),
path('mark-as-present/comic/<int:pk>/', path('mark-as-present/bd/<int:pk>/',
views.MarkComicAsPresent.as_view(), views.MarkComicAsPresent.as_view(),
name="mark_comic_as_present"), name="mark_comic_as_present"),
path('mark-as-present/manga/<int:pk>/', path('mark-as-present/manga/<int:pk>/',
@ -21,15 +21,15 @@ urlpatterns = [
path('mark-as-present/cd/<int:pk>/', path('mark-as-present/cd/<int:pk>/',
views.MarkCDAsPresent.as_view(), views.MarkCDAsPresent.as_view(),
name="mark_cd_as_present"), name="mark_cd_as_present"),
path('mark-as-present/vinyl/<int:pk>/', path('mark-as-present/vinyle/<int:pk>/',
views.MarkVinylAsPresent.as_view(), views.MarkVinylAsPresent.as_view(),
name="mark_vinyle_as_present"), name="mark_vinyle_as_present"),
path('mark-as-present/novel/<int:pk>/', path('mark-as-present/roman/<int:pk>/',
views.MarkNovelAsPresent.as_view(), views.MarkRomanAsPresent.as_view(),
name="mark_novel_as_present"), name="mark_roman_as_present"),
path('mark-as-present/review/<int:pk>/', path('mark-as-present/revue/<int:pk>/',
views.MarkReviewAsPresent.as_view(), views.MarkRevueAsPresent.as_view(),
name="mark_review_as_present"), name="mark_revue_as_present"),
path('mark-as-present/future/<int:pk>/', path('mark-as-present/future/<int:pk>/',
views.MarkFutureAsPresent.as_view(), views.MarkFutureAsPresent.as_view(),
name="mark_future_as_present"), name="mark_future_as_present"),

View File

@ -81,11 +81,11 @@ class MarkVinylAsPresent(MarkMediumAsPresent):
model = Vinyl model = Vinyl
class MarkNovelAsPresent(MarkMediumAsPresent): class MarkRomanAsPresent(MarkMediumAsPresent):
model = Novel model = Novel
class MarkReviewAsPresent(MarkMediumAsPresent): class MarkRevueAsPresent(MarkMediumAsPresent):
model = Review model = Review

View File

@ -1,7 +1,6 @@
docutils~=0.16 # for Django-admin docs docutils~=0.16 # for Django-admin docs
Django~=2.2 Django~=2.2
django-filter~=2.4 django-filter~=2.4
django-polymorphic~=3.0
django-reversion~=3.0 django-reversion~=3.0
djangorestframework~=3.12 djangorestframework~=3.12
django_extensions~=3.0 django_extensions~=3.0