diff --git a/med/admin.py b/med/admin.py index acb795d..78a27b2 100644 --- a/med/admin.py +++ b/med/admin.py @@ -7,7 +7,7 @@ from django.contrib.auth.admin import Group, GroupAdmin from django.contrib.sites.admin import Site, SiteAdmin from django.utils.translation import gettext_lazy as _ from django.views.decorators.cache import never_cache -from media.models import Emprunt +from media.models import Borrow class DatabaseAdmin(AdminSite): @@ -22,8 +22,8 @@ class DatabaseAdmin(AdminSite): # User is always authenticated # Get currently borrowed items - user_borrowed = Emprunt.objects.filter(user=request.user, - date_rendu=None) + user_borrowed = Borrow.objects.filter(user=request.user, + given_back=None) response.context_data["borrowed_items"] = user_borrowed return response diff --git a/med/settings.py b/med/settings.py index 2b89e58..2947467 100644 --- a/med/settings.py +++ b/med/settings.py @@ -167,8 +167,6 @@ PAGINATION_NUMBER = 25 AUTH_USER_MODEL = 'users.User' -MAX_EMPRUNT = 5 # Max emprunts - # AUTHLIB CLIENTS AUTHLIB_OAUTH_CLIENTS = { 'notekfet': { diff --git a/med/urls.py b/med/urls.py index e286a50..e8fe86d 100644 --- a/med/urls.py +++ b/med/urls.py @@ -21,7 +21,7 @@ router.register(r'media/vinyl', media.views.VinylViewSet) router.register(r'media/novel', media.views.NovelViewSet) router.register(r'media/review', media.views.ReviewViewSet) router.register(r'media/future', media.views.FutureMediumViewSet) -router.register(r'borrowed_items', media.views.EmpruntViewSet) +router.register(r'borrowed_items', media.views.BorrowViewSet) router.register(r'games', media.views.GameViewSet) router.register(r'users', users.views.UserViewSet) router.register(r'groups', users.views.GroupViewSet) diff --git a/media/admin.py b/media/admin.py index 8a11026..631b1ec 100644 --- a/media/admin.py +++ b/media/admin.py @@ -11,7 +11,7 @@ from med.admin import admin_site from reversion.admin import VersionAdmin from .forms import MediaAdminForm -from .models import Author, Borrowable, CD, Comic, Emprunt, FutureMedium, \ +from .models import Author, Borrow, Borrowable, CD, Comic, FutureMedium, \ Game, Manga, Novel, Review, Vinyl @@ -120,30 +120,15 @@ class ReviewAdmin(VersionAdmin, PolymorphicChildModelAdmin): show_in_index = True -class EmpruntAdmin(VersionAdmin): - list_display = ('media', 'user', 'date_emprunt', 'date_rendu', - 'permanencier_emprunt', 'permanencier_rendu_custom') - search_fields = ('media__title', 'media__side_identifier', - 'user__username', 'date_emprunt', 'date_rendu') - date_hierarchy = 'date_emprunt' - autocomplete_fields = ('media', 'user', 'permanencier_emprunt', - 'permanencier_rendu') - - def permanencier_rendu_custom(self, obj): - """ - Show a button if item has not been returned yet - """ - if obj.permanencier_rendu: - return obj.permanencier_rendu - else: - return format_html( - '{}', - reverse('media:retour-emprunt', args=[obj.pk]), - _('Turn back') - ) - - permanencier_rendu_custom.short_description = _('given back to') - permanencier_rendu_custom.allow_tags = True +class BorrowAdmin(VersionAdmin): + list_display = ('borrowable', 'user', 'borrow_date', 'borrowed_with', + 'given_back_to') + search_fields = ('borrowable__isbn', 'borrowable__title', + 'borrowable__medium__side_identifier', + 'user__username', 'borrow_date', 'given_back') + date_hierarchy = 'borrow_date' + autocomplete_fields = ('borrowable', 'user', 'borrowed_with', + 'given_back_to') def add_view(self, request, form_url='', extra_context=None): """ @@ -151,7 +136,7 @@ class EmpruntAdmin(VersionAdmin): """ # Make GET data mutable data = request.GET.copy() - data['permanencier_emprunt'] = request.user + data['borrowed_with'] = request.user request.GET = data return super().add_view(request, form_url, extra_context) @@ -173,5 +158,5 @@ admin_site.register(CD, CDAdmin) admin_site.register(Vinyl, VinylAdmin) admin_site.register(Review, ReviewAdmin) admin_site.register(FutureMedium, FutureMediumAdmin) -admin_site.register(Emprunt, EmpruntAdmin) +admin_site.register(Borrow, BorrowAdmin) admin_site.register(Game, GameAdmin) diff --git a/media/locale/fr/LC_MESSAGES/django.po b/media/locale/fr/LC_MESSAGES/django.po index 7e2ba46..6c0d5bc 100644 --- a/media/locale/fr/LC_MESSAGES/django.po +++ b/media/locale/fr/LC_MESSAGES/django.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-26 15:14+0200\n" +"POT-Creation-Date: 2021-11-14 14:25+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -13,8 +13,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: admin.py:46 admin.py:102 admin.py:114 models.py:30 models.py:77 -#: models.py:149 models.py:221 models.py:290 models.py:348 models.py:394 +#: admin.py:46 admin.py:102 admin.py:114 models.py:30 models.py:85 msgid "authors" msgstr "auteurs" @@ -22,55 +21,47 @@ msgstr "auteurs" msgid "external url" msgstr "URL externe" -#: admin.py:142 -msgid "Turn back" -msgstr "Rendre" - -#: admin.py:145 models.py:574 -msgid "given back to" -msgstr "rendu à" - #: fields.py:17 msgid "ISBN-10 or ISBN-13" msgstr "ISBN-10 ou ISBN-13" -#: forms.py:301 +#: forms.py:302 msgid "This ISBN is not found." msgstr "L'ISBN n'a pas été trouvé." -#: management/commands/migrate_to_new_format.py:52 models.py:408 models.py:415 +#: management/commands/migrate_to_new_format.py:57 models.py:156 msgid "CDs" msgstr "CDs" -#: management/commands/migrate_to_new_format.py:52 models.py:407 models.py:414 +#: management/commands/migrate_to_new_format.py:57 models.py:155 msgid "CD" msgstr "CD" -#: management/commands/migrate_to_new_format.py:68 models.py:362 models.py:377 +#: management/commands/migrate_to_new_format.py:73 models.py:149 msgid "vinyls" msgstr "vinyles" -#: management/commands/migrate_to_new_format.py:68 models.py:361 models.py:376 +#: management/commands/migrate_to_new_format.py:73 models.py:148 msgid "vinyl" msgstr "vinyle" -#: management/commands/migrate_to_new_format.py:86 models.py:466 models.py:506 +#: management/commands/migrate_to_new_format.py:91 models.py:196 msgid "reviews" msgstr "revues" -#: management/commands/migrate_to_new_format.py:86 models.py:465 models.py:505 +#: management/commands/migrate_to_new_format.py:91 models.py:195 msgid "review" msgstr "revue" -#: management/commands/migrate_to_new_format.py:106 models.py:629 models.py:670 +#: management/commands/migrate_to_new_format.py:111 models.py:315 msgid "games" msgstr "jeux" -#: management/commands/migrate_to_new_format.py:106 models.py:628 models.py:669 +#: management/commands/migrate_to_new_format.py:111 models.py:314 msgid "game" msgstr "jeu" -#: models.py:17 models.py:598 +#: models.py:17 msgid "name" msgstr "nom" @@ -82,63 +73,59 @@ msgstr "note" 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 +#: models.py:36 models.py:202 msgid "ISBN" msgstr "ISBN" -#: models.py:88 models.py:120 models.py:192 models.py:261 models.py:513 +#: models.py:37 models.py:203 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 +#: models.py:45 +msgid "title" +msgstr "titre" + +#: models.py:49 models.py:220 +msgid "present" +msgstr "présent" + +#: models.py:50 models.py:221 +msgid "Tell that the medium is present in the Mediatek." +msgstr "Indique que le medium est présent à la Mediatek." + +#: models.py:68 +msgid "borrowable" +msgstr "empruntable" + +#: models.py:69 +msgid "borrowables" +msgstr "empruntables" + +#: models.py:74 +msgid "external URL" +msgstr "URL externe" + +#: models.py:79 +msgid "side identifier" +msgstr "côte" + +#: models.py:89 +msgid "medium" +msgstr "medium" + +#: models.py:90 +msgid "media" +msgstr "media" + +#: models.py:95 msgid "subtitle" msgstr "sous-titre" -#: models.py:101 models.py:153 models.py:225 models.py:294 +#: models.py:101 msgid "number of pages" msgstr "nombre de pages" -#: models.py:107 models.py:159 models.py:231 models.py:300 +#: models.py:107 msgid "publish date" msgstr "date de publication" @@ -150,135 +137,143 @@ msgstr "livre" msgid "books" msgstr "livres" -#: models.py:177 models.py:184 +#: models.py:119 msgid "comic" msgstr "BD" -#: models.py:178 models.py:185 +#: models.py:120 msgid "comics" msgstr "BDs" -#: models.py:246 models.py:253 +#: models.py:126 msgid "manga" msgstr "manga" -#: models.py:247 models.py:254 +#: models.py:127 msgid "mangas" msgstr "mangas" -#: models.py:315 models.py:322 +#: models.py:133 msgid "novel" msgstr "roman" -#: models.py:316 models.py:323 +#: models.py:134 msgid "novels" msgstr "romans" -#: models.py:339 models.py:368 +#: models.py:140 msgid "rounds per minute" msgstr "tours par minute" -#: models.py:341 models.py:370 +#: models.py:142 msgid "33 RPM" msgstr "33 TPM" -#: models.py:342 models.py:371 +#: models.py:143 msgid "45 RPM" msgstr "45 TPM" -#: models.py:426 models.py:472 +#: models.py:162 msgid "number" msgstr "nombre" -#: models.py:430 models.py:476 +#: models.py:166 msgid "year" msgstr "année" -#: models.py:437 models.py:483 +#: models.py:173 msgid "month" msgstr "mois" -#: models.py:444 models.py:490 +#: models.py:180 msgid "day" msgstr "jour" -#: models.py:451 models.py:497 +#: models.py:187 msgid "double" msgstr "double" -#: models.py:520 +#: models.py:210 msgid "type" msgstr "type" -#: models.py:522 +#: models.py:212 msgid "Comic" msgstr "BD" -#: models.py:523 +#: models.py:213 msgid "Manga" msgstr "Manga" -#: models.py:524 +#: models.py:214 msgid "Roman" msgstr "Roman" -#: models.py:536 +#: models.py:226 msgid "future medium" msgstr "medium à importer" -#: models.py:537 +#: models.py:227 msgid "future media" msgstr "medias à importer" -#: models.py:551 +#: models.py:237 +msgid "object" +msgstr "objet" + +#: models.py:242 msgid "borrower" msgstr "emprunteur" -#: models.py:554 +#: models.py:245 msgid "borrowed on" msgstr "emprunté le" -#: models.py:559 +#: models.py:250 msgid "given back on" msgstr "rendu le" -#: models.py:565 +#: models.py:256 msgid "borrowed with" msgstr "emprunté avec" -#: models.py:566 +#: models.py:257 msgid "The keyholder that registered this borrowed item." msgstr "Le permanencier qui enregistre cet emprunt." -#: models.py:575 +#: models.py:265 +msgid "given back to" +msgstr "rendu à" + +#: models.py:266 msgid "The keyholder to whom this item was given back." msgstr "Le permanencier à qui l'emprunt a été rendu." -#: models.py:582 +#: models.py:273 msgid "borrowed item" msgstr "emprunt" -#: models.py:583 +#: models.py:274 msgid "borrowed items" msgstr "emprunts" -#: models.py:603 models.py:644 +#: models.py:289 msgid "owner" msgstr "propriétaire" -#: models.py:608 models.py:649 +#: models.py:294 msgid "duration" msgstr "durée" -#: models.py:612 models.py:653 +#: models.py:298 msgid "minimum number of players" msgstr "nombre minimum de joueurs" -#: models.py:616 models.py:657 +#: models.py:302 msgid "maximum number of players" msgstr "nombre maximum de joueurs" -#: models.py:621 models.py:662 +#: models.py:307 msgid "comment" msgstr "commentaire" @@ -306,6 +301,6 @@ msgstr "ISBN invalide : mauvaise longueur" msgid "Invalid ISBN: Only upper case allowed" msgstr "ISBN invalide : seulement les majuscules sont autorisées" -#: views.py:47 +#: views.py:25 msgid "Welcome to the Mediatek database" msgstr "Bienvenue sur la base de données de la Mediatek" diff --git a/media/migrations/0045_auto_20211114_1423.py b/media/migrations/0045_auto_20211114_1423.py new file mode 100644 index 0000000..a719a07 --- /dev/null +++ b/media/migrations/0045_auto_20211114_1423.py @@ -0,0 +1,36 @@ +# Generated by Django 2.2.24 on 2021-11-14 13:23 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('media', '0044_auto_20211102_1254'), + ] + + operations = [ + migrations.CreateModel( + name='Borrow', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('borrow_date', models.DateTimeField(verbose_name='borrowed on')), + ('given_back', models.DateTimeField(blank=True, null=True, verbose_name='given back on')), + ('borrowable', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='media.Borrowable', verbose_name='object')), + ('borrowed_with', models.ForeignKey(help_text='The keyholder that registered this borrowed item.', on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='borrowed with')), + ('given_back_to', models.ForeignKey(blank=True, help_text='The keyholder to whom this item was given back.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='given back to')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL, verbose_name='borrower')), + ], + options={ + 'verbose_name': 'borrowed item', + 'verbose_name_plural': 'borrowed items', + 'ordering': ['-borrow_date'], + }, + ), + migrations.DeleteModel( + name='Emprunt', + ), + ] diff --git a/media/models.py b/media/models.py index 2d5ccfb..eda6597 100644 --- a/media/models.py +++ b/media/models.py @@ -1,7 +1,7 @@ # -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2017-2021 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later - +from django.conf import settings from django.core.validators import MinValueValidator from django.db import models from django.utils.translation import gettext_lazy as _ @@ -230,35 +230,36 @@ class FutureMedium(models.Model): return "Future medium (ISBN: {isbn})".format(isbn=self.isbn, ) -class Emprunt(models.Model): - media = models.ForeignKey( +class Borrow(models.Model): + borrowable = models.ForeignKey( 'media.Borrowable', on_delete=models.PROTECT, + verbose_name=_('object'), ) user = models.ForeignKey( - 'users.User', + settings.AUTH_USER_MODEL, on_delete=models.PROTECT, verbose_name=_("borrower"), ) - date_emprunt = models.DateTimeField( + borrow_date = models.DateTimeField( verbose_name=_('borrowed on'), ) - date_rendu = models.DateTimeField( + given_back = models.DateTimeField( blank=True, null=True, verbose_name=_('given back on'), ) - permanencier_emprunt = models.ForeignKey( - 'users.User', + borrowed_with = models.ForeignKey( + settings.AUTH_USER_MODEL, on_delete=models.PROTECT, - related_name='user_permanencier_emprunt', + related_name='+', verbose_name=_('borrowed with'), help_text=_('The keyholder that registered this borrowed item.') ) - permanencier_rendu = models.ForeignKey( - 'users.User', + given_back_to = models.ForeignKey( + settings.AUTH_USER_MODEL, on_delete=models.PROTECT, - related_name='user_permanencier_rendu', + related_name='+', blank=True, null=True, verbose_name=_('given back to'), @@ -266,12 +267,12 @@ class Emprunt(models.Model): ) def __str__(self): - return str(self.media) + str(self.user) + return str(self.borrowable) + str(self.user) class Meta: verbose_name = _("borrowed item") verbose_name_plural = _("borrowed items") - ordering = ['-date_emprunt'] + ordering = ['-borrow_date'] class Game(Borrowable): diff --git a/media/serializers.py b/media/serializers.py index 97c0ff5..aea4f08 100644 --- a/media/serializers.py +++ b/media/serializers.py @@ -1,6 +1,6 @@ from rest_framework import serializers -from .models import Author, CD, Comic, FutureMedium, Manga, Emprunt, Game, \ +from .models import Author, Borrow, CD, Comic, FutureMedium, Manga, Game, \ Novel, Review, Vinyl @@ -52,15 +52,13 @@ class FutureMediumSerializer(serializers.ModelSerializer): fields = '__all__' -class EmpruntSerializer(serializers.HyperlinkedModelSerializer): +class BorrowSerializer(serializers.HyperlinkedModelSerializer): class Meta: - model = Emprunt - fields = ['url', 'media', 'user', 'date_emprunt', 'date_rendu', - 'permanencier_emprunt', 'permanencier_rendu'] + model = Borrow + fields = '__all__' class GameSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Game - fields = ['url', 'name', 'proprietaire', 'duree', 'nombre_joueurs_min', - 'nombre_joueurs_max', 'comment'] + fields = '__all__' diff --git a/media/tests/test_templates.py b/media/tests/test_templates.py index d6bf8b9..15b6df9 100644 --- a/media/tests/test_templates.py +++ b/media/tests/test_templates.py @@ -55,10 +55,10 @@ class TemplateTests(TestCase): ), data=data) self.assertEqual(response.status_code, 302) - def test_comic_emprunt_changelist(self): - response = self.client.get(reverse('admin:media_emprunt_changelist')) + def test_comic_borrow_changelist(self): + response = self.client.get(reverse('admin:media_borrow_changelist')) self.assertEqual(response.status_code, 200) - def test_comic_emprunt_add(self): - response = self.client.get(reverse('admin:media_emprunt_add')) + def test_comic_borrow_add(self): + response = self.client.get(reverse('admin:media_borrow_add')) self.assertEqual(response.status_code, 200) diff --git a/media/urls.py b/media/urls.py index 261d559..973bf45 100644 --- a/media/urls.py +++ b/media/urls.py @@ -2,15 +2,12 @@ # Copyright (C) 2017-2019 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later -from django.conf.urls import url from django.urls import path from . import views app_name = 'media' urlpatterns = [ - url(r'^retour_emprunt/(?P[0-9]+)$', views.retour_emprunt, - name='retour-emprunt'), path('find/', views.FindMediumView.as_view(), name="find"), path('mark-as-present/comic//', views.MarkComicAsPresent.as_view(), diff --git a/media/views.py b/media/views.py index bd0e2f4..4934079 100644 --- a/media/views.py +++ b/media/views.py @@ -2,42 +2,20 @@ # Copyright (C) 2017-2019 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later -from django.contrib import messages -from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.mixins import LoginRequiredMixin from django.http import HttpResponse from django_filters.rest_framework import DjangoFilterBackend -from django.db import transaction from django.shortcuts import redirect -from django.utils import timezone from django.utils.translation import gettext_lazy as _ from django.views.generic import TemplateView, DetailView from rest_framework import viewsets from rest_framework.filters import SearchFilter -from reversion import revisions as reversion -from .models import Author, CD, Comic, Emprunt, FutureMedium, Game, Manga,\ +from .models import Author, Borrow, CD, Comic, FutureMedium, Game, Manga,\ Novel, Review, Vinyl -from .serializers import AuthorSerializer, ComicSerializer, CDSerializer,\ - EmpruntSerializer, FutureMediumSerializer, GameSerializer, \ - MangaSerializer, NovelSerializer, ReviewSerializer, VinylSerializer - - -@login_required -@permission_required('media.change_emprunt') -def retour_emprunt(request, empruntid): - try: - emprunt_instance = Emprunt.objects.get(pk=empruntid) - except Emprunt.DoesNotExist: - messages.error(request, u"Entrée inexistante") - return redirect("admin:media_emprunt_changelist") - with transaction.atomic(), reversion.create_revision(): - emprunt_instance.permanencier_rendu = request.user - emprunt_instance.date_rendu = timezone.now() - emprunt_instance.save() - reversion.set_user(request.user) - messages.success(request, "Retour enregistré") - return redirect("admin:media_emprunt_changelist") +from .serializers import AuthorSerializer, BorrowSerializer, ComicSerializer, \ + CDSerializer, FutureMediumSerializer, GameSerializer, MangaSerializer, \ + NovelSerializer, ReviewSerializer, VinylSerializer class IndexView(TemplateView): @@ -181,12 +159,12 @@ class FutureMediumViewSet(viewsets.ModelViewSet): search_fields = ["=isbn"] -class EmpruntViewSet(viewsets.ModelViewSet): +class BorrowViewSet(viewsets.ModelViewSet): """ API endpoint that allows borrowed items to be viewed or edited. """ - queryset = Emprunt.objects.all() - serializer_class = EmpruntSerializer + queryset = Borrow.objects.all() + serializer_class = BorrowSerializer class GameViewSet(viewsets.ModelViewSet): diff --git a/theme/templates/admin/index.html b/theme/templates/admin/index.html index 67dcce1..4b285ff 100644 --- a/theme/templates/admin/index.html +++ b/theme/templates/admin/index.html @@ -64,10 +64,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
  • {% trans 'date joined' %} : {{ user.date_joined }}
  • {% trans 'last login' %} : {{ user.last_login }}
  • {% trans 'address' %} : {{ user.address }}
  • -
  • {% trans 'phone number' %} : {{ user.telephone }}
  • +
  • {% trans 'phone number' %} : {{ user.phone_number }}
  • {% trans 'groups' %} : {% for g in user.groups.all %}{{ g.name }} {% endfor %}
  • -
  • {% trans 'maximum borrowed' %} : {{ user.maxemprunt }}
  • {% trans 'membership for current year' %} : {% if user.is_member %} @@ -81,8 +80,8 @@ SPDX-License-Identifier: GPL-3.0-or-later

    {% trans 'Current borrowed items' %}

    {% if borrowed_items %}
      - {% for emprunt in borrowed_items %} -
    • {{ emprunt.media }} ({% trans 'since' %} {{ emprunt.date_emprunt }})
    • + {% for borrow in borrowed_items %} +
    • {{ borrow.object }} ({% trans 'since' %} {{ borrow.borrow_date }})
    • {% endfor %}
    {% else %} diff --git a/users/admin.py b/users/admin.py index 6849ef6..b097694 100644 --- a/users/admin.py +++ b/users/admin.py @@ -12,7 +12,6 @@ from django.utils.translation import ugettext_lazy as _ from reversion.admin import VersionAdmin from med.admin import admin_site -from .forms import UserCreationAdminForm from .models import User @@ -35,28 +34,17 @@ class UserAdmin(VersionAdmin, BaseUserAdmin): fieldsets = ( (None, {'fields': ('username', 'password')}), (_('Personal info'), {'fields': ('first_name', 'last_name', 'email', - 'telephone', 'address', 'comment')}), + 'phone_number', 'address', + 'comment')}), (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', - 'groups', 'user_permissions', - 'maxemprunt')}), + 'groups', 'user_permissions')}), (_('Important dates'), {'fields': ('last_login', 'date_joined')}), ) list_display = ('username', 'email', 'first_name', 'last_name', - 'maxemprunt', 'is_member', 'is_staff') + 'is_member', 'is_staff') list_filter = (IsMemberFilter, 'is_staff', 'is_superuser', 'is_active', 'groups') - # Customize required initial fields - add_form_template = 'admin/change_form.html' - add_form = UserCreationAdminForm - add_fieldsets = ( - (None, { - 'classes': ('wide',), - 'fields': ("username", "email", "first_name", "last_name", - "address", "telephone"), - }), - ) - def save_model(self, request, obj, form, change): """ On creation, send a password init mail diff --git a/users/forms.py b/users/forms.py deleted file mode 100644 index 41f0a9b..0000000 --- a/users/forms.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay -# SPDX-License-Identifier: GPL-3.0-or-later - -from django import forms -from django.contrib.auth.forms import UsernameField -from django.core.validators import MinLengthValidator -from django.forms import ModelForm - -from .models import User - - -class PassForm(forms.Form): - passwd1 = forms.CharField( - label=u'Nouveau mot de passe', - max_length=255, - validators=[MinLengthValidator(8)], - widget=forms.PasswordInput, - ) - passwd2 = forms.CharField( - label=u'Saisir à nouveau le mot de passe', - max_length=255, - validators=[MinLengthValidator(8)], - widget=forms.PasswordInput - ) - - -class BaseInfoForm(ModelForm): - class Meta: - model = User - fields = [ - 'username', - 'email', - 'first_name', - 'last_name', - 'address', - 'telephone', - ] - - -class UserCreationAdminForm(ModelForm): - """ - A form that creates a user, with no privileges, - from the given information. - """ - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.fields['email'].required = True - self.fields['first_name'].required = True - self.fields['last_name'].required = True - - class Meta: - model = User - fields = ("username", "email", "first_name", "last_name", "address", - "telephone") - field_classes = {'username': UsernameField} diff --git a/users/migrations/0045_auto_20211114_1423.py b/users/migrations/0045_auto_20211114_1423.py new file mode 100644 index 0000000..6bca1cd --- /dev/null +++ b/users/migrations/0045_auto_20211114_1423.py @@ -0,0 +1,22 @@ +# Generated by Django 2.2.24 on 2021-11-14 13:23 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0044_membership'), + ] + + operations = [ + migrations.RenameField( + model_name='user', + old_name='telephone', + new_name='phone_number', + ), + migrations.RemoveField( + model_name='user', + name='maxemprunt', + ), + ] diff --git a/users/models.py b/users/models.py index c6e93fa..44b937b 100644 --- a/users/models.py +++ b/users/models.py @@ -1,5 +1,5 @@ # -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2017-2021 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from datetime import datetime @@ -12,11 +12,10 @@ from django.db import models from django.db.models import Q from django.utils import timezone from django.utils.translation import gettext_lazy as _ -from med.settings import MAX_EMPRUNT class User(AbstractUser): - telephone = models.CharField( + phone_number = models.CharField( verbose_name=_('phone number'), max_length=15, blank=True, @@ -26,12 +25,6 @@ class User(AbstractUser): max_length=255, blank=True, ) - maxemprunt = models.IntegerField( - verbose_name=_('maximum borrowed'), - help_text=_('Maximal amount of simultaneous borrowed item ' - 'authorized.'), - default=MAX_EMPRUNT, - ) comment = models.CharField( verbose_name=_('comment'), help_text=_('Promotion...'), @@ -39,7 +32,7 @@ class User(AbstractUser): blank=True, ) date_joined = models.DateTimeField( - _('date joined'), + verbose_name=_('date joined'), default=timezone.now, null=True, ) @@ -69,7 +62,7 @@ class User(AbstractUser): self.email = data['email'] self.first_name = data['first_name'] self.last_name = data['last_name'] - self.telephone = data['profile']['phone_number'] + self.phone_number = data['profile']['phone_number'] self.address = data['profile']['address'] self.comment = data['profile']['section'] diff --git a/users/serializers.py b/users/serializers.py index e1b5faf..6dfd05a 100644 --- a/users/serializers.py +++ b/users/serializers.py @@ -8,7 +8,7 @@ class UserSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = User fields = ['url', 'username', 'first_name', 'last_name', 'email', - 'groups', 'telephone', 'address', 'maxemprunt', 'comment', + 'groups', 'phone_number', 'address', 'comment', 'date_joined']