mirror of
https://gitlab.crans.org/mediatek/med.git
synced 2024-11-27 10:13:02 +00:00
Merge branch 'medium' into 'main'
Migration des données See merge request mediatek/med!5
This commit is contained in:
commit
8c6828564c
@ -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-reversion python3-djangorestframework
|
python3-django python3-django-polymorphic python3-django-reversion
|
||||||
python3-docutils python3-requests tox
|
python3-djangorestframework python3-docutils python3-requests tox
|
||||||
script: tox -e py39
|
script: tox -e py39
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
|
@ -36,6 +36,7 @@ INSTALLED_APPS = [
|
|||||||
'reversion',
|
'reversion',
|
||||||
'rest_framework',
|
'rest_framework',
|
||||||
'django_extensions',
|
'django_extensions',
|
||||||
|
'polymorphic',
|
||||||
|
|
||||||
# Django contrib
|
# Django contrib
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
|
@ -5,12 +5,14 @@
|
|||||||
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, CD, Comic, Emprunt, FutureMedium, Game, Manga,\
|
from .models import Author, Borrowable, CD, Comic, Emprunt, FutureMedium, \
|
||||||
Novel, Review, Vinyl
|
Game, Manga, Novel, Review, Vinyl
|
||||||
|
|
||||||
|
|
||||||
class AuthorAdmin(VersionAdmin):
|
class AuthorAdmin(VersionAdmin):
|
||||||
@ -18,7 +20,17 @@ class AuthorAdmin(VersionAdmin):
|
|||||||
search_fields = ('name',)
|
search_fields = ('name',)
|
||||||
|
|
||||||
|
|
||||||
class MediumAdmin(VersionAdmin):
|
class BorrowableAdmin(PolymorphicParentModelAdmin):
|
||||||
|
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',
|
||||||
@ -26,6 +38,7 @@ class MediumAdmin(VersionAdmin):
|
|||||||
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()])
|
||||||
@ -77,10 +90,11 @@ class FutureMediumAdmin(VersionAdmin):
|
|||||||
extra_context=extra_context)
|
extra_context=extra_context)
|
||||||
|
|
||||||
|
|
||||||
class CDAdmin(VersionAdmin):
|
class CDAdmin(VersionAdmin, PolymorphicChildModelAdmin):
|
||||||
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()])
|
||||||
@ -88,10 +102,11 @@ class CDAdmin(VersionAdmin):
|
|||||||
authors_list.short_description = _('authors')
|
authors_list.short_description = _('authors')
|
||||||
|
|
||||||
|
|
||||||
class VinylAdmin(VersionAdmin):
|
class VinylAdmin(VersionAdmin, PolymorphicChildModelAdmin):
|
||||||
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()])
|
||||||
@ -99,9 +114,10 @@ class VinylAdmin(VersionAdmin):
|
|||||||
authors_list.short_description = _('authors')
|
authors_list.short_description = _('authors')
|
||||||
|
|
||||||
|
|
||||||
class ReviewAdmin(VersionAdmin):
|
class ReviewAdmin(VersionAdmin, PolymorphicChildModelAdmin):
|
||||||
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):
|
||||||
@ -140,14 +156,16 @@ class EmpruntAdmin(VersionAdmin):
|
|||||||
return super().add_view(request, form_url, extra_context)
|
return super().add_view(request, form_url, extra_context)
|
||||||
|
|
||||||
|
|
||||||
class GameAdmin(VersionAdmin):
|
class GameAdmin(VersionAdmin, PolymorphicChildModelAdmin):
|
||||||
list_display = ('name', 'owner', 'duration', 'players_min',
|
list_display = ('title', '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)
|
||||||
|
@ -9,6 +9,7 @@ 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 _
|
||||||
@ -320,6 +321,13 @@ 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
|
||||||
@ -329,7 +337,6 @@ 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 \
|
||||||
|
@ -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-23 18:27+0200\n"
|
"POT-Creation-Date: 2021-10-26 15:14+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:33 admin.py:88 admin.py:99 models.py:29 models.py:65 models.py:130
|
#: admin.py:46 admin.py:102 admin.py:114 models.py:30 models.py:77
|
||||||
#: models.py:192 models.py:243 models.py:274
|
#: models.py:149 models.py:221 models.py:290 models.py:348 models.py:394
|
||||||
msgid "authors"
|
msgid "authors"
|
||||||
msgstr "auteurs"
|
msgstr "auteurs"
|
||||||
|
|
||||||
#: admin.py:43
|
#: admin.py:56
|
||||||
msgid "external url"
|
msgid "external url"
|
||||||
msgstr "URL externe"
|
msgstr "URL externe"
|
||||||
|
|
||||||
#: admin.py:126
|
#: admin.py:142
|
||||||
msgid "Turn back"
|
msgid "Turn back"
|
||||||
msgstr "Rendre"
|
msgstr "Rendre"
|
||||||
|
|
||||||
#: admin.py:129 models.py:407
|
#: admin.py:145 models.py:574
|
||||||
msgid "given back to"
|
msgid "given back to"
|
||||||
msgstr "rendu à"
|
msgstr "rendu à"
|
||||||
|
|
||||||
@ -38,220 +38,249 @@ 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é."
|
||||||
|
|
||||||
#: models.py:16 models.py:431
|
#: management/commands/migrate_to_new_format.py:52 models.py:408 models.py:415
|
||||||
msgid "name"
|
|
||||||
msgstr "nom"
|
|
||||||
|
|
||||||
#: models.py:21
|
|
||||||
msgid "note"
|
|
||||||
msgstr "note"
|
|
||||||
|
|
||||||
#: models.py:28
|
|
||||||
msgid "author"
|
|
||||||
msgstr "auteur"
|
|
||||||
|
|
||||||
#: models.py:35 models.py:100 models.py:162 models.py:345
|
|
||||||
msgid "ISBN"
|
|
||||||
msgstr "ISBN"
|
|
||||||
|
|
||||||
#: models.py:36 models.py:101 models.py:163 models.py:346
|
|
||||||
msgid "You may be able to scan it from a bar code."
|
|
||||||
msgstr "Peut souvent être scanné à partir du code barre."
|
|
||||||
|
|
||||||
#: 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"
|
|
||||||
msgstr "sous-titre"
|
|
||||||
|
|
||||||
#: 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"
|
|
||||||
msgstr "nombre de pages"
|
|
||||||
|
|
||||||
#: models.py:75 models.py:140 models.py:202
|
|
||||||
msgid "publish date"
|
|
||||||
msgstr "date de publication"
|
|
||||||
|
|
||||||
#: models.py:81 models.py:146 models.py:208 models.py:247 models.py:278
|
|
||||||
#: models.py:329 models.py:363
|
|
||||||
msgid "present"
|
|
||||||
msgstr "présent"
|
|
||||||
|
|
||||||
#: models.py:82 models.py:147 models.py:209 models.py:248 models.py:279
|
|
||||||
#: models.py:330 models.py:364
|
|
||||||
msgid "Tell that the medium is present in the Mediatek."
|
|
||||||
msgstr "Indique que le medium est présent à la Mediatek."
|
|
||||||
|
|
||||||
#: models.py:93 models.py:355
|
|
||||||
msgid "comic"
|
|
||||||
msgstr "BD"
|
|
||||||
|
|
||||||
#: models.py:94
|
|
||||||
msgid "comics"
|
|
||||||
msgstr "BDs"
|
|
||||||
|
|
||||||
#: models.py:155
|
|
||||||
msgid "manga"
|
|
||||||
msgstr "manga"
|
|
||||||
|
|
||||||
#: models.py:156
|
|
||||||
msgid "mangas"
|
|
||||||
msgstr "mangas"
|
|
||||||
|
|
||||||
#: models.py:217
|
|
||||||
msgid "novel"
|
|
||||||
msgstr "roman"
|
|
||||||
|
|
||||||
#: models.py:218
|
|
||||||
msgid "novels"
|
|
||||||
msgstr "romans"
|
|
||||||
|
|
||||||
#: models.py:234
|
|
||||||
msgid "rounds per minute"
|
|
||||||
msgstr "tours par minute"
|
|
||||||
|
|
||||||
#: models.py:236
|
|
||||||
msgid "33 RPM"
|
|
||||||
msgstr "33 TPM"
|
|
||||||
|
|
||||||
#: models.py:237
|
|
||||||
msgid "45 RPM"
|
|
||||||
msgstr "45 TPM"
|
|
||||||
|
|
||||||
#: 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"
|
msgid "CDs"
|
||||||
msgstr "CDs"
|
msgstr "CDs"
|
||||||
|
|
||||||
#: models.py:299
|
#: management/commands/migrate_to_new_format.py:52 models.py:407 models.py:414
|
||||||
msgid "number"
|
msgid "CD"
|
||||||
msgstr "nombre"
|
msgstr "CD"
|
||||||
|
|
||||||
#: models.py:303
|
#: management/commands/migrate_to_new_format.py:68 models.py:362 models.py:377
|
||||||
msgid "year"
|
msgid "vinyls"
|
||||||
msgstr "année"
|
msgstr "vinyles"
|
||||||
|
|
||||||
#: models.py:310
|
#: management/commands/migrate_to_new_format.py:68 models.py:361 models.py:376
|
||||||
msgid "month"
|
msgid "vinyl"
|
||||||
msgstr "mois"
|
msgstr "vinyle"
|
||||||
|
|
||||||
#: models.py:317
|
#: management/commands/migrate_to_new_format.py:86 models.py:466 models.py:506
|
||||||
msgid "day"
|
|
||||||
msgstr "jour"
|
|
||||||
|
|
||||||
#: models.py:324
|
|
||||||
msgid "double"
|
|
||||||
msgstr "double"
|
|
||||||
|
|
||||||
#: models.py:338
|
|
||||||
msgid "review"
|
|
||||||
msgstr "revue"
|
|
||||||
|
|
||||||
#: models.py:339
|
|
||||||
msgid "reviews"
|
msgid "reviews"
|
||||||
msgstr "revues"
|
msgstr "revues"
|
||||||
|
|
||||||
#: models.py:353
|
#: management/commands/migrate_to_new_format.py:86 models.py:465 models.py:505
|
||||||
msgid "type"
|
msgid "review"
|
||||||
msgstr "type"
|
msgstr "revue"
|
||||||
|
|
||||||
#: models.py:356
|
#: management/commands/migrate_to_new_format.py:106 models.py:629 models.py:670
|
||||||
msgid "Manga"
|
msgid "games"
|
||||||
msgstr "Manga"
|
msgstr "jeux"
|
||||||
|
|
||||||
#: models.py:357
|
#: management/commands/migrate_to_new_format.py:106 models.py:628 models.py:669
|
||||||
msgid "Roman"
|
|
||||||
msgstr "Roman"
|
|
||||||
|
|
||||||
#: models.py:369
|
|
||||||
msgid "future medium"
|
|
||||||
msgstr "medium à importer"
|
|
||||||
|
|
||||||
#: models.py:370
|
|
||||||
msgid "future media"
|
|
||||||
msgstr "medias à importer"
|
|
||||||
|
|
||||||
#: models.py:384
|
|
||||||
msgid "borrower"
|
|
||||||
msgstr "emprunteur"
|
|
||||||
|
|
||||||
#: models.py:387
|
|
||||||
msgid "borrowed on"
|
|
||||||
msgstr "emprunté le"
|
|
||||||
|
|
||||||
#: models.py:392
|
|
||||||
msgid "given back on"
|
|
||||||
msgstr "rendu le"
|
|
||||||
|
|
||||||
#: models.py:398
|
|
||||||
msgid "borrowed with"
|
|
||||||
msgstr "emprunté avec"
|
|
||||||
|
|
||||||
#: models.py:399
|
|
||||||
msgid "The keyholder that registered this borrowed item."
|
|
||||||
msgstr "Le permanencier qui enregistre cet emprunt."
|
|
||||||
|
|
||||||
#: models.py:408
|
|
||||||
msgid "The keyholder to whom this item was given back."
|
|
||||||
msgstr "Le permanencier à qui l'emprunt a été rendu."
|
|
||||||
|
|
||||||
#: models.py:415
|
|
||||||
msgid "borrowed item"
|
|
||||||
msgstr "emprunt"
|
|
||||||
|
|
||||||
#: models.py:416
|
|
||||||
msgid "borrowed items"
|
|
||||||
msgstr "emprunts"
|
|
||||||
|
|
||||||
#: models.py:436
|
|
||||||
msgid "owner"
|
|
||||||
msgstr "propriétaire"
|
|
||||||
|
|
||||||
#: models.py:441
|
|
||||||
msgid "duration"
|
|
||||||
msgstr "durée"
|
|
||||||
|
|
||||||
#: models.py:445
|
|
||||||
msgid "minimum number of players"
|
|
||||||
msgstr "nombre minimum de joueurs"
|
|
||||||
|
|
||||||
#: models.py:449
|
|
||||||
msgid "maximum number of players"
|
|
||||||
msgstr "nombre maximum de joueurs"
|
|
||||||
|
|
||||||
#: models.py:454
|
|
||||||
msgid "comment"
|
|
||||||
msgstr "commentaire"
|
|
||||||
|
|
||||||
#: models.py:461
|
|
||||||
msgid "game"
|
msgid "game"
|
||||||
msgstr "jeu"
|
msgstr "jeu"
|
||||||
|
|
||||||
#: models.py:462
|
#: models.py:17 models.py:598
|
||||||
msgid "games"
|
msgid "name"
|
||||||
msgstr "jeux"
|
msgstr "nom"
|
||||||
|
|
||||||
|
#: models.py:22
|
||||||
|
msgid "note"
|
||||||
|
msgstr "note"
|
||||||
|
|
||||||
|
#: models.py:29
|
||||||
|
msgid "author"
|
||||||
|
msgstr "auteur"
|
||||||
|
|
||||||
|
#: models.py:37 models.py:127 models.py:199 models.py:268 models.py:329
|
||||||
|
#: 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"
|
||||||
|
msgstr "ISBN"
|
||||||
|
|
||||||
|
#: models.py:88 models.py:120 models.py:192 models.py:261 models.py:513
|
||||||
|
msgid "You may be able to scan it from a bar code."
|
||||||
|
msgstr "Peut souvent être scanné à partir du code barre."
|
||||||
|
|
||||||
|
#: models.py:95 models.py:132 models.py:204 models.py:273
|
||||||
|
msgid "subtitle"
|
||||||
|
msgstr "sous-titre"
|
||||||
|
|
||||||
|
#: models.py:101 models.py:153 models.py:225 models.py:294
|
||||||
|
msgid "number of pages"
|
||||||
|
msgstr "nombre de pages"
|
||||||
|
|
||||||
|
#: models.py:107 models.py:159 models.py:231 models.py:300
|
||||||
|
msgid "publish date"
|
||||||
|
msgstr "date de publication"
|
||||||
|
|
||||||
|
#: models.py:113
|
||||||
|
msgid "book"
|
||||||
|
msgstr "livre"
|
||||||
|
|
||||||
|
#: models.py:114
|
||||||
|
msgid "books"
|
||||||
|
msgstr "livres"
|
||||||
|
|
||||||
|
#: models.py:177 models.py:184
|
||||||
|
msgid "comic"
|
||||||
|
msgstr "BD"
|
||||||
|
|
||||||
|
#: models.py:178 models.py:185
|
||||||
|
msgid "comics"
|
||||||
|
msgstr "BDs"
|
||||||
|
|
||||||
|
#: models.py:246 models.py:253
|
||||||
|
msgid "manga"
|
||||||
|
msgstr "manga"
|
||||||
|
|
||||||
|
#: models.py:247 models.py:254
|
||||||
|
msgid "mangas"
|
||||||
|
msgstr "mangas"
|
||||||
|
|
||||||
|
#: models.py:315 models.py:322
|
||||||
|
msgid "novel"
|
||||||
|
msgstr "roman"
|
||||||
|
|
||||||
|
#: models.py:316 models.py:323
|
||||||
|
msgid "novels"
|
||||||
|
msgstr "romans"
|
||||||
|
|
||||||
|
#: models.py:339 models.py:368
|
||||||
|
msgid "rounds per minute"
|
||||||
|
msgstr "tours par minute"
|
||||||
|
|
||||||
|
#: models.py:341 models.py:370
|
||||||
|
msgid "33 RPM"
|
||||||
|
msgstr "33 TPM"
|
||||||
|
|
||||||
|
#: models.py:342 models.py:371
|
||||||
|
msgid "45 RPM"
|
||||||
|
msgstr "45 TPM"
|
||||||
|
|
||||||
|
#: models.py:426 models.py:472
|
||||||
|
msgid "number"
|
||||||
|
msgstr "nombre"
|
||||||
|
|
||||||
|
#: models.py:430 models.py:476
|
||||||
|
msgid "year"
|
||||||
|
msgstr "année"
|
||||||
|
|
||||||
|
#: models.py:437 models.py:483
|
||||||
|
msgid "month"
|
||||||
|
msgstr "mois"
|
||||||
|
|
||||||
|
#: models.py:444 models.py:490
|
||||||
|
msgid "day"
|
||||||
|
msgstr "jour"
|
||||||
|
|
||||||
|
#: models.py:451 models.py:497
|
||||||
|
msgid "double"
|
||||||
|
msgstr "double"
|
||||||
|
|
||||||
|
#: models.py:520
|
||||||
|
msgid "type"
|
||||||
|
msgstr "type"
|
||||||
|
|
||||||
|
#: models.py:522
|
||||||
|
msgid "Comic"
|
||||||
|
msgstr "BD"
|
||||||
|
|
||||||
|
#: models.py:523
|
||||||
|
msgid "Manga"
|
||||||
|
msgstr "Manga"
|
||||||
|
|
||||||
|
#: models.py:524
|
||||||
|
msgid "Roman"
|
||||||
|
msgstr "Roman"
|
||||||
|
|
||||||
|
#: models.py:536
|
||||||
|
msgid "future medium"
|
||||||
|
msgstr "medium à importer"
|
||||||
|
|
||||||
|
#: models.py:537
|
||||||
|
msgid "future media"
|
||||||
|
msgstr "medias à importer"
|
||||||
|
|
||||||
|
#: models.py:551
|
||||||
|
msgid "borrower"
|
||||||
|
msgstr "emprunteur"
|
||||||
|
|
||||||
|
#: models.py:554
|
||||||
|
msgid "borrowed on"
|
||||||
|
msgstr "emprunté le"
|
||||||
|
|
||||||
|
#: models.py:559
|
||||||
|
msgid "given back on"
|
||||||
|
msgstr "rendu le"
|
||||||
|
|
||||||
|
#: models.py:565
|
||||||
|
msgid "borrowed with"
|
||||||
|
msgstr "emprunté avec"
|
||||||
|
|
||||||
|
#: models.py:566
|
||||||
|
msgid "The keyholder that registered this borrowed item."
|
||||||
|
msgstr "Le permanencier qui enregistre cet emprunt."
|
||||||
|
|
||||||
|
#: models.py:575
|
||||||
|
msgid "The keyholder to whom this item was given back."
|
||||||
|
msgstr "Le permanencier à qui l'emprunt a été rendu."
|
||||||
|
|
||||||
|
#: models.py:582
|
||||||
|
msgid "borrowed item"
|
||||||
|
msgstr "emprunt"
|
||||||
|
|
||||||
|
#: models.py:583
|
||||||
|
msgid "borrowed items"
|
||||||
|
msgstr "emprunts"
|
||||||
|
|
||||||
|
#: models.py:603 models.py:644
|
||||||
|
msgid "owner"
|
||||||
|
msgstr "propriétaire"
|
||||||
|
|
||||||
|
#: models.py:608 models.py:649
|
||||||
|
msgid "duration"
|
||||||
|
msgstr "durée"
|
||||||
|
|
||||||
|
#: models.py:612 models.py:653
|
||||||
|
msgid "minimum number of players"
|
||||||
|
msgstr "nombre minimum de joueurs"
|
||||||
|
|
||||||
|
#: models.py:616 models.py:657
|
||||||
|
msgid "maximum number of players"
|
||||||
|
msgstr "nombre maximum de joueurs"
|
||||||
|
|
||||||
|
#: models.py:621 models.py:662
|
||||||
|
msgid "comment"
|
||||||
|
msgstr "commentaire"
|
||||||
|
|
||||||
#: templates/media/generate_side_identifier.html:3
|
#: templates/media/generate_side_identifier.html:3
|
||||||
msgid "Generate side identifier"
|
msgid "Generate side identifier"
|
||||||
@ -277,6 +306,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:51
|
#: views.py:47
|
||||||
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"
|
||||||
|
127
media/management/commands/migrate_to_new_format.py
Normal file
127
media/management/commands/migrate_to_new_format.py
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
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, \
|
||||||
|
OldCD, OldComic, OldGame, OldManga, OldNovel, OldReview, OldVinyl
|
||||||
|
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
|
||||||
|
# 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)
|
70
media/migrations/0042_auto_20211023_1929.py
Normal file
70
media/migrations/0042_auto_20211023_1929.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# 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'},
|
||||||
|
),
|
||||||
|
]
|
166
media/migrations/0043_auto_20211023_2012.py
Normal file
166
media/migrations/0043_auto_20211023_2012.py
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
# 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',),
|
||||||
|
),
|
||||||
|
]
|
230
media/models.py
230
media/models.py
@ -5,6 +5,7 @@
|
|||||||
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
|
||||||
|
|
||||||
@ -30,7 +31,90 @@ class Author(models.Model):
|
|||||||
ordering = ['name']
|
ordering = ['name']
|
||||||
|
|
||||||
|
|
||||||
class Comic(models.Model):
|
class Borrowable(PolymorphicModel):
|
||||||
|
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(
|
||||||
|
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):
|
||||||
|
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(
|
||||||
|
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 OldComic(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.'),
|
||||||
@ -95,7 +179,14 @@ class Comic(models.Model):
|
|||||||
ordering = ['title', 'subtitle']
|
ordering = ['title', 'subtitle']
|
||||||
|
|
||||||
|
|
||||||
class Manga(models.Model):
|
class Comic(Book):
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("comic")
|
||||||
|
verbose_name_plural = _("comics")
|
||||||
|
ordering = ['title', 'subtitle']
|
||||||
|
|
||||||
|
|
||||||
|
class OldManga(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.'),
|
||||||
@ -157,7 +248,14 @@ class Manga(models.Model):
|
|||||||
ordering = ['title']
|
ordering = ['title']
|
||||||
|
|
||||||
|
|
||||||
class Novel(models.Model):
|
class Manga(Book):
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("manga")
|
||||||
|
verbose_name_plural = _("mangas")
|
||||||
|
ordering = ['title', 'subtitle']
|
||||||
|
|
||||||
|
|
||||||
|
class OldNovel(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.'),
|
||||||
@ -219,7 +317,14 @@ class Novel(models.Model):
|
|||||||
ordering = ['title', 'subtitle']
|
ordering = ['title', 'subtitle']
|
||||||
|
|
||||||
|
|
||||||
class Vinyl(models.Model):
|
class Novel(Book):
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("novel")
|
||||||
|
verbose_name_plural = _("novels")
|
||||||
|
ordering = ['title', 'subtitle']
|
||||||
|
|
||||||
|
|
||||||
|
class OldVinyl(models.Model):
|
||||||
title = models.CharField(
|
title = models.CharField(
|
||||||
verbose_name=_('title'),
|
verbose_name=_('title'),
|
||||||
max_length=255,
|
max_length=255,
|
||||||
@ -258,7 +363,22 @@ class Vinyl(models.Model):
|
|||||||
ordering = ['title']
|
ordering = ['title']
|
||||||
|
|
||||||
|
|
||||||
class CD(models.Model):
|
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 OldCD(models.Model):
|
||||||
title = models.CharField(
|
title = models.CharField(
|
||||||
verbose_name=_('title'),
|
verbose_name=_('title'),
|
||||||
max_length=255,
|
max_length=255,
|
||||||
@ -289,7 +409,14 @@ class CD(models.Model):
|
|||||||
ordering = ['title']
|
ordering = ['title']
|
||||||
|
|
||||||
|
|
||||||
class Review(models.Model):
|
class CD(Medium):
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("CD")
|
||||||
|
verbose_name_plural = _("CDs")
|
||||||
|
ordering = ['title']
|
||||||
|
|
||||||
|
|
||||||
|
class OldReview(models.Model):
|
||||||
title = models.CharField(
|
title = models.CharField(
|
||||||
verbose_name=_('title'),
|
verbose_name=_('title'),
|
||||||
max_length=255,
|
max_length=255,
|
||||||
@ -340,6 +467,46 @@ class Review(models.Model):
|
|||||||
ordering = ['title', 'number']
|
ordering = ['title', 'number']
|
||||||
|
|
||||||
|
|
||||||
|
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']
|
||||||
|
|
||||||
|
|
||||||
class FutureMedium(models.Model):
|
class FutureMedium(models.Model):
|
||||||
isbn = ISBNField(
|
isbn = ISBNField(
|
||||||
_('ISBN'),
|
_('ISBN'),
|
||||||
@ -375,7 +542,7 @@ class FutureMedium(models.Model):
|
|||||||
|
|
||||||
class Emprunt(models.Model):
|
class Emprunt(models.Model):
|
||||||
media = models.ForeignKey(
|
media = models.ForeignKey(
|
||||||
'Comic',
|
'media.Borrowable',
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
)
|
)
|
||||||
user = models.ForeignKey(
|
user = models.ForeignKey(
|
||||||
@ -417,7 +584,7 @@ class Emprunt(models.Model):
|
|||||||
ordering = ['-date_emprunt']
|
ordering = ['-date_emprunt']
|
||||||
|
|
||||||
|
|
||||||
class Game(models.Model):
|
class OldGame(models.Model):
|
||||||
DURATIONS = (
|
DURATIONS = (
|
||||||
('-1h', '-1h'),
|
('-1h', '-1h'),
|
||||||
('1-2h', '1-2h'),
|
('1-2h', '1-2h'),
|
||||||
@ -426,7 +593,7 @@ class Game(models.Model):
|
|||||||
('4h+', '4h+'),
|
('4h+', '4h+'),
|
||||||
)
|
)
|
||||||
|
|
||||||
name = models.CharField(
|
title = models.CharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
verbose_name=_("name"),
|
verbose_name=_("name"),
|
||||||
)
|
)
|
||||||
@ -455,9 +622,50 @@ class Game(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.name)
|
return str(self.title)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("game")
|
verbose_name = _("game")
|
||||||
verbose_name_plural = _("games")
|
verbose_name_plural = _("games")
|
||||||
ordering = ['name']
|
ordering = ['title']
|
||||||
|
|
||||||
|
|
||||||
|
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']
|
||||||
|
@ -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/bd/?search=' + isbn, true);
|
bd_request.open('GET', '/api/media/comic/?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(bd => {
|
data.results.forEach(comic => {
|
||||||
let present = bd.present;
|
let present = comic.present;
|
||||||
if (markAsPresent && isbn === bd.isbn) {
|
if (markAsPresent && isbn === comic.isbn) {
|
||||||
present = true;
|
present = true;
|
||||||
let presentRequest = new XMLHttpRequest();
|
let presentRequest = new XMLHttpRequest();
|
||||||
presentRequest.open("GET", "/media/mark-as-present/bd/" + bd.id + "/", true);
|
presentRequest.open("GET", "/media/mark-as-present/bd/" + comic.id + "/", true);
|
||||||
presentRequest.send();
|
presentRequest.send();
|
||||||
}
|
}
|
||||||
result_div.innerHTML += "<li id='bd_" + bd.id + "'>" +
|
result_div.innerHTML += "<li id='comic_" + comic.id + "'>" +
|
||||||
"<a href='/database/media/bd/" + bd.id + "/change/'>BD : "
|
"<a href='/database/media/comic/" + comic.id + "/change/'>BD : "
|
||||||
+ bd.title + (bd.subtitle ? " - " + bd.subtitle : "") + "</a>"
|
+ comic.title + (comic.subtitle ? " - " + comic.subtitle : "") + "</a>"
|
||||||
+ (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('bd', " + bd.id + ", false)\">marquer comme absent</a>)"
|
+ (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('bd', " + comic.id + ", false)\">marquer comme absent</a>)"
|
||||||
: " (absent, <a class='present' href='#' onclick=\"markAsPresent('bd', " + bd.id + ")\">marquer comme présent</a>)") + "</li>";
|
: " (absent, <a class='present' href='#' onclick=\"markAsPresent('bd', " + comic.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/vinyle/?search=' + isbn, true);
|
vinyle_request.open('GET', '/api/media/vinyl/?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(vinyle => {
|
data.results.forEach(vinyl => {
|
||||||
let present = markAsPresent || vinyle.present;
|
let present = markAsPresent || vinyl.present;
|
||||||
result_div.innerHTML += "<li id='vinyle_" + vinyle.id + "'>" +
|
result_div.innerHTML += "<li id='vinyl_" + vinyl.id + "'>" +
|
||||||
"<a href='/database/media/vinyle/" + vinyle.id + "/change/'>Vinyle : " + vinyle.title + "</a>"
|
"<a href='/database/media/vinyl/" + vinyl.id + "/change/'>Vinyle : " + vinyl.title + "</a>"
|
||||||
+ (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('vinyle', " + vinyle.id + ", false)\">marquer comme absent</a>)"
|
+ (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('vinyl', " + vinyl.id + ", false)\">marquer comme absent</a>)"
|
||||||
: " (absent, <a class='present' href='#' onclick=\"markAsPresent('vinyle', " + vinyle.id + ")\">marquer comme présent</a>)") + "</li>";
|
: " (absent, <a class='present' href='#' onclick=\"markAsPresent('vinyl', " + vinyl.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/roman/?search=' + isbn, true);
|
roman_request.open('GET', '/api/media/novel/?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(roman => {
|
data.results.forEach(novel => {
|
||||||
let present = roman.present;
|
let present = novel.present;
|
||||||
if (markAsPresent && isbn === roman.isbn) {
|
if (markAsPresent && isbn === novel.isbn) {
|
||||||
present = true;
|
present = true;
|
||||||
let presentRequest = new XMLHttpRequest();
|
let presentRequest = new XMLHttpRequest();
|
||||||
presentRequest.open("GET", "/media/mark-as-present/roman/" + roman.id + "/", true);
|
presentRequest.open("GET", "/media/mark-as-present/novel/" + novel.id + "/", true);
|
||||||
presentRequest.send();
|
presentRequest.send();
|
||||||
}
|
}
|
||||||
result_div.innerHTML += "<li id='roman_" + roman.id + "'>" +
|
result_div.innerHTML += "<li id='roman_" + novel.id + "'>" +
|
||||||
"<a href='/database/media/roman/" + roman.id + "/change/'>Roman : " + roman.title + "</a>"
|
"<a href='/database/media/roman/" + novel.id + "/change/'>Roman : " + novel.title + "</a>"
|
||||||
+ (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('roman', " + roman.id + ", false)\">marquer comme absent</a>)"
|
+ (present ? " (<a class='absent' href='#' onclick=\"markAsPresent('novel', " + novel.id + ", false)\">marquer comme absent</a>)"
|
||||||
: " (absent, <a class='present' href='#' onclick=\"markAsPresent('roman', " + roman.id + ")\">marquer comme présent</a>)") + "</li>";
|
: " (absent, <a class='present' href='#' onclick=\"markAsPresent('novel', " + novel.id + ")\">marquer comme présent</a>)") + "</li>";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
roman_request.send();
|
roman_request.send();
|
||||||
|
@ -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/bd/<int:pk>/',
|
path('mark-as-present/comic/<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/vinyle/<int:pk>/',
|
path('mark-as-present/vinyl/<int:pk>/',
|
||||||
views.MarkVinylAsPresent.as_view(),
|
views.MarkVinylAsPresent.as_view(),
|
||||||
name="mark_vinyle_as_present"),
|
name="mark_vinyle_as_present"),
|
||||||
path('mark-as-present/roman/<int:pk>/',
|
path('mark-as-present/novel/<int:pk>/',
|
||||||
views.MarkRomanAsPresent.as_view(),
|
views.MarkNovelAsPresent.as_view(),
|
||||||
name="mark_roman_as_present"),
|
name="mark_novel_as_present"),
|
||||||
path('mark-as-present/revue/<int:pk>/',
|
path('mark-as-present/review/<int:pk>/',
|
||||||
views.MarkRevueAsPresent.as_view(),
|
views.MarkReviewAsPresent.as_view(),
|
||||||
name="mark_revue_as_present"),
|
name="mark_review_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"),
|
||||||
|
@ -81,11 +81,11 @@ class MarkVinylAsPresent(MarkMediumAsPresent):
|
|||||||
model = Vinyl
|
model = Vinyl
|
||||||
|
|
||||||
|
|
||||||
class MarkRomanAsPresent(MarkMediumAsPresent):
|
class MarkNovelAsPresent(MarkMediumAsPresent):
|
||||||
model = Novel
|
model = Novel
|
||||||
|
|
||||||
|
|
||||||
class MarkRevueAsPresent(MarkMediumAsPresent):
|
class MarkReviewAsPresent(MarkMediumAsPresent):
|
||||||
model = Review
|
model = Review
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
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
|
||||||
|
Loading…
Reference in New Issue
Block a user