mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-22 06:03:20 +00:00
core, counter: add preferences for counter notifications
Signed-off-by: Skia <skia@libskia.so>
This commit is contained in:
parent
914feffbd8
commit
9f259b35bd
35
core/migrations/0023_auto_20170902_1226.py
Normal file
35
core/migrations/0023_auto_20170902_1226.py
Normal file
@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0022_auto_20170822_2232'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='preferences',
|
||||
name='notify_on_click',
|
||||
field=models.BooleanField(verbose_name='get a notification for every click', default=False),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='preferences',
|
||||
name='notify_on_refill',
|
||||
field=models.BooleanField(verbose_name='get a notification for every refilling', default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='preferences',
|
||||
name='show_my_stats',
|
||||
field=models.BooleanField(verbose_name='show your stats to others', default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='preferences',
|
||||
name='user',
|
||||
field=models.OneToOneField(related_name='_preferences', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
@ -497,6 +497,15 @@ class User(AbstractBaseUser):
|
||||
def subscribed(self):
|
||||
return self.is_in_group(settings.SITH_MAIN_MEMBERS_GROUP)
|
||||
|
||||
@cached_property
|
||||
def preferences(self):
|
||||
try:
|
||||
return self._preferences
|
||||
except:
|
||||
prefs = Preferences(user=self)
|
||||
prefs.save()
|
||||
return prefs
|
||||
|
||||
@cached_property
|
||||
def forum_infos(self):
|
||||
try:
|
||||
@ -582,16 +591,22 @@ class AnonymousUser(AuthAnonymousUser):
|
||||
|
||||
|
||||
class Preferences(models.Model):
|
||||
user = models.OneToOneField(User, related_name="preferences")
|
||||
user = models.OneToOneField(User, related_name="_preferences")
|
||||
receive_weekmail = models.BooleanField(
|
||||
_('do you want to receive the weekmail'),
|
||||
default=False,
|
||||
# help_text=_('Do you want to receive the weekmail?'),
|
||||
)
|
||||
show_my_stats = models.BooleanField(
|
||||
_('define if we show a users stats'),
|
||||
_('show your stats to others'),
|
||||
default=False,
|
||||
)
|
||||
notify_on_click = models.BooleanField(
|
||||
_('get a notification for every click'),
|
||||
default=False,
|
||||
)
|
||||
notify_on_refill = models.BooleanField(
|
||||
_('get a notification for every refilling'),
|
||||
default=False,
|
||||
help_text=_('Show your account statistics to others'),
|
||||
)
|
||||
|
||||
def get_display_name(self):
|
||||
|
@ -464,7 +464,8 @@ class UserPreferencesView(UserTabsMixin, CanEditMixin, UpdateView):
|
||||
model = User
|
||||
pk_url_kwarg = "user_id"
|
||||
template_name = "core/user_preferences.jinja"
|
||||
form_class = modelform_factory(Preferences, fields=['receive_weekmail'])
|
||||
form_class = modelform_factory(Preferences, fields=['receive_weekmail',
|
||||
'notify_on_click', 'notify_on_refill'])
|
||||
context_object_name = "profile"
|
||||
current_tab = "prefs"
|
||||
|
||||
@ -474,11 +475,7 @@ class UserPreferencesView(UserTabsMixin, CanEditMixin, UpdateView):
|
||||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super(UserPreferencesView, self).get_form_kwargs()
|
||||
try:
|
||||
pref = self.object.preferences
|
||||
except:
|
||||
pref = Preferences(user=self.object)
|
||||
pref.save()
|
||||
kwargs.update({'instance': pref})
|
||||
return kwargs
|
||||
|
||||
|
@ -326,6 +326,7 @@ class Refilling(models.Model):
|
||||
self.customer.amount += self.amount
|
||||
self.customer.save()
|
||||
self.is_validated = True
|
||||
if self.customer.user.preferences.notify_on_refill:
|
||||
Notification(user=self.customer.user, url=reverse('core:user_account_detail',
|
||||
kwargs={'user_id': self.customer.user.id, 'year': self.date.year, 'month': self.date.month}),
|
||||
param=str(self.amount),
|
||||
@ -444,6 +445,7 @@ class Selling(models.Model):
|
||||
self.send_mail_customer()
|
||||
except:
|
||||
pass
|
||||
if self.customer.user.preferences.notify_on_click:
|
||||
Notification(
|
||||
user=self.customer.user,
|
||||
url=reverse('core:user_account_detail',
|
||||
|
@ -6,7 +6,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-09-02 02:16+0200\n"
|
||||
"POT-Creation-Date: 2017-09-02 12:33+0200\n"
|
||||
"PO-Revision-Date: 2016-07-18\n"
|
||||
"Last-Translator: Skia <skia@libskia.so>\n"
|
||||
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
||||
@ -88,12 +88,12 @@ msgstr "Compte club"
|
||||
msgid "%(club_account)s on %(bank_account)s"
|
||||
msgstr "%(club_account)s sur %(bank_account)s"
|
||||
|
||||
#: accounting/models.py:195 club/models.py:190 counter/models.py:463
|
||||
#: accounting/models.py:195 club/models.py:190 counter/models.py:465
|
||||
#: election/models.py:16 launderette/models.py:148
|
||||
msgid "start date"
|
||||
msgstr "date de début"
|
||||
|
||||
#: accounting/models.py:196 club/models.py:191 counter/models.py:464
|
||||
#: accounting/models.py:196 club/models.py:191 counter/models.py:466
|
||||
#: election/models.py:17
|
||||
msgid "end date"
|
||||
msgstr "date de fin"
|
||||
@ -127,18 +127,18 @@ msgstr "numéro"
|
||||
msgid "journal"
|
||||
msgstr "classeur"
|
||||
|
||||
#: accounting/models.py:258 core/models.py:628 core/models.py:1003
|
||||
#: core/models.py:1044 counter/models.py:300 counter/models.py:349
|
||||
#: counter/models.py:481 eboutic/models.py:39 eboutic/models.py:73
|
||||
#: accounting/models.py:258 core/models.py:643 core/models.py:1018
|
||||
#: core/models.py:1059 counter/models.py:300 counter/models.py:350
|
||||
#: counter/models.py:483 eboutic/models.py:39 eboutic/models.py:73
|
||||
#: forum/models.py:239 forum/models.py:314 stock/models.py:76
|
||||
msgid "date"
|
||||
msgstr "date"
|
||||
|
||||
#: accounting/models.py:259 counter/models.py:482 stock/models.py:79
|
||||
#: accounting/models.py:259 counter/models.py:484 stock/models.py:79
|
||||
msgid "comment"
|
||||
msgstr "commentaire"
|
||||
|
||||
#: accounting/models.py:260 counter/models.py:301 counter/models.py:350
|
||||
#: accounting/models.py:260 counter/models.py:301 counter/models.py:351
|
||||
#: subscription/models.py:55
|
||||
msgid "payment method"
|
||||
msgstr "méthode de paiement"
|
||||
@ -164,7 +164,7 @@ msgid "accounting type"
|
||||
msgstr "type comptable"
|
||||
|
||||
#: accounting/models.py:269 accounting/models.py:371 accounting/models.py:398
|
||||
#: accounting/models.py:422 counter/models.py:341
|
||||
#: accounting/models.py:422 counter/models.py:342
|
||||
msgid "label"
|
||||
msgstr "étiquette"
|
||||
|
||||
@ -888,7 +888,7 @@ msgstr "Vous ne pouvez pas faire de boucles dans les clubs"
|
||||
msgid "A club with that unix_name already exists"
|
||||
msgstr "Un club avec ce nom UNIX existe déjà."
|
||||
|
||||
#: club/models.py:188 counter/models.py:461 counter/models.py:479
|
||||
#: club/models.py:188 counter/models.py:463 counter/models.py:481
|
||||
#: eboutic/models.py:38 eboutic/models.py:72 election/models.py:140
|
||||
#: launderette/models.py:114 launderette/models.py:152 sas/models.py:158
|
||||
#: trombi/models.py:148
|
||||
@ -927,7 +927,7 @@ msgid "Enter a valid address. Only the root of the address is needed."
|
||||
msgstr ""
|
||||
"Entrez une adresse valide. Seule la racine de l'adresse est nécessaire."
|
||||
|
||||
#: club/models.py:238 com/models.py:67 core/models.py:629
|
||||
#: club/models.py:238 com/models.py:67 core/models.py:644
|
||||
msgid "is moderated"
|
||||
msgstr "est modéré"
|
||||
|
||||
@ -1262,7 +1262,7 @@ msgstr "résumé"
|
||||
msgid "content"
|
||||
msgstr "contenu"
|
||||
|
||||
#: com/models.py:64 core/models.py:1043 launderette/models.py:86
|
||||
#: com/models.py:64 core/models.py:1058 launderette/models.py:86
|
||||
#: launderette/models.py:112 launderette/models.py:149 stock/models.py:59
|
||||
#: stock/models.py:98
|
||||
msgid "type"
|
||||
@ -1931,109 +1931,113 @@ msgstr "Un utilisateur de ce nom d'utilisateur existe déjà"
|
||||
msgid "Profile"
|
||||
msgstr "Profil"
|
||||
|
||||
#: core/models.py:581
|
||||
#: core/models.py:590
|
||||
msgid "Visitor"
|
||||
msgstr "Visiteur"
|
||||
|
||||
#: core/models.py:587
|
||||
#: core/models.py:596
|
||||
msgid "do you want to receive the weekmail"
|
||||
msgstr "voulez-vous recevoir le Weekmail"
|
||||
|
||||
#: core/models.py:592
|
||||
msgid "define if we show a users stats"
|
||||
msgstr "Definit si l'on montre les statistiques de l'utilisateur"
|
||||
#: core/models.py:600
|
||||
msgid "show your stats to others"
|
||||
msgstr "montrez vos statistiques aux autres"
|
||||
|
||||
#: core/models.py:594
|
||||
msgid "Show your account statistics to others"
|
||||
msgstr "Montrez vos statistiques de compte aux autres"
|
||||
#: core/models.py:604
|
||||
msgid "get a notification for every click"
|
||||
msgstr "recevez une notification pour chaque click"
|
||||
|
||||
#: core/models.py:617
|
||||
#: core/models.py:608
|
||||
msgid "get a notification for every refilling"
|
||||
msgstr "recevez une notification pour chaque rechargement"
|
||||
|
||||
#: core/models.py:632
|
||||
msgid "file name"
|
||||
msgstr "nom du fichier"
|
||||
|
||||
#: core/models.py:618 core/models.py:829
|
||||
#: core/models.py:633 core/models.py:844
|
||||
msgid "parent"
|
||||
msgstr "parent"
|
||||
|
||||
#: core/models.py:619 core/models.py:635
|
||||
#: core/models.py:634 core/models.py:650
|
||||
msgid "file"
|
||||
msgstr "fichier"
|
||||
|
||||
#: core/models.py:620
|
||||
#: core/models.py:635
|
||||
msgid "compressed file"
|
||||
msgstr "version allégée"
|
||||
|
||||
#: core/models.py:621
|
||||
#: core/models.py:636
|
||||
msgid "thumbnail"
|
||||
msgstr "miniature"
|
||||
|
||||
#: core/models.py:622 core/models.py:630
|
||||
#: core/models.py:637 core/models.py:645
|
||||
msgid "owner"
|
||||
msgstr "propriétaire"
|
||||
|
||||
#: core/models.py:623 core/models.py:835 core/views/files.py:149
|
||||
#: core/models.py:638 core/models.py:850 core/views/files.py:149
|
||||
msgid "edit group"
|
||||
msgstr "groupe d'édition"
|
||||
|
||||
#: core/models.py:624 core/models.py:836 core/views/files.py:150
|
||||
#: core/models.py:639 core/models.py:851 core/views/files.py:150
|
||||
msgid "view group"
|
||||
msgstr "groupe de vue"
|
||||
|
||||
#: core/models.py:625
|
||||
#: core/models.py:640
|
||||
msgid "is folder"
|
||||
msgstr "est un dossier"
|
||||
|
||||
#: core/models.py:626
|
||||
#: core/models.py:641
|
||||
msgid "mime type"
|
||||
msgstr "type mime"
|
||||
|
||||
#: core/models.py:627
|
||||
#: core/models.py:642
|
||||
msgid "size"
|
||||
msgstr "taille"
|
||||
|
||||
#: core/models.py:631
|
||||
#: core/models.py:646
|
||||
msgid "asked for removal"
|
||||
msgstr "retrait demandé"
|
||||
|
||||
#: core/models.py:632
|
||||
#: core/models.py:647
|
||||
msgid "is in the SAS"
|
||||
msgstr "est dans le SAS"
|
||||
|
||||
#: core/models.py:671
|
||||
#: core/models.py:686
|
||||
msgid "Character '/' not authorized in name"
|
||||
msgstr "Le caractère '/' n'est pas autorisé dans les noms de fichier"
|
||||
|
||||
#: core/models.py:674 core/models.py:679
|
||||
#: core/models.py:689 core/models.py:694
|
||||
msgid "Loop in folder tree"
|
||||
msgstr "Boucle dans l'arborescence des dossiers"
|
||||
|
||||
#: core/models.py:683
|
||||
#: core/models.py:698
|
||||
msgid "You can not make a file be a children of a non folder file"
|
||||
msgstr ""
|
||||
"Vous ne pouvez pas mettre un fichier enfant de quelque chose qui n'est pas "
|
||||
"un dossier"
|
||||
|
||||
#: core/models.py:687
|
||||
#: core/models.py:702
|
||||
msgid "Duplicate file"
|
||||
msgstr "Un fichier de ce nom existe déjà"
|
||||
|
||||
#: core/models.py:701
|
||||
#: core/models.py:716
|
||||
msgid "You must provide a file"
|
||||
msgstr "Vous devez fournir un fichier"
|
||||
|
||||
#: core/models.py:767
|
||||
#: core/models.py:782
|
||||
msgid "Folder: "
|
||||
msgstr "Dossier : "
|
||||
|
||||
#: core/models.py:769
|
||||
#: core/models.py:784
|
||||
msgid "File: "
|
||||
msgstr "Fichier : "
|
||||
|
||||
#: core/models.py:821
|
||||
#: core/models.py:836
|
||||
msgid "page unix name"
|
||||
msgstr "nom unix de la page"
|
||||
|
||||
#: core/models.py:825
|
||||
#: core/models.py:840
|
||||
msgid ""
|
||||
"Enter a valid page name. This value may contain only unaccented letters, "
|
||||
"numbers and ./+/-/_ characters."
|
||||
@ -2041,51 +2045,51 @@ msgstr ""
|
||||
"Entrez un nom de page correct. Uniquement des lettres non accentuées, "
|
||||
"numéros, et ./+/-/_"
|
||||
|
||||
#: core/models.py:832
|
||||
#: core/models.py:847
|
||||
msgid "page name"
|
||||
msgstr "nom de la page"
|
||||
|
||||
#: core/models.py:833
|
||||
#: core/models.py:848
|
||||
msgid "owner group"
|
||||
msgstr "groupe propriétaire"
|
||||
|
||||
#: core/models.py:837
|
||||
#: core/models.py:852
|
||||
msgid "lock user"
|
||||
msgstr "utilisateur bloquant"
|
||||
|
||||
#: core/models.py:838
|
||||
#: core/models.py:853
|
||||
msgid "lock_timeout"
|
||||
msgstr "décompte du déblocage"
|
||||
|
||||
#: core/models.py:865
|
||||
#: core/models.py:880
|
||||
msgid "Duplicate page"
|
||||
msgstr "Une page de ce nom existe déjà"
|
||||
|
||||
#: core/models.py:871
|
||||
#: core/models.py:886
|
||||
msgid "Loop in page tree"
|
||||
msgstr "Boucle dans l'arborescence des pages"
|
||||
|
||||
#: core/models.py:1000
|
||||
#: core/models.py:1015
|
||||
msgid "revision"
|
||||
msgstr "révision"
|
||||
|
||||
#: core/models.py:1001
|
||||
#: core/models.py:1016
|
||||
msgid "page title"
|
||||
msgstr "titre de la page"
|
||||
|
||||
#: core/models.py:1002
|
||||
#: core/models.py:1017
|
||||
msgid "page content"
|
||||
msgstr "contenu de la page"
|
||||
|
||||
#: core/models.py:1041
|
||||
#: core/models.py:1056
|
||||
msgid "url"
|
||||
msgstr "url"
|
||||
|
||||
#: core/models.py:1042
|
||||
#: core/models.py:1057
|
||||
msgid "param"
|
||||
msgstr "param"
|
||||
|
||||
#: core/models.py:1045
|
||||
#: core/models.py:1060
|
||||
msgid "viewed"
|
||||
msgstr "vue"
|
||||
|
||||
@ -3160,7 +3164,7 @@ msgstr "groupe d'achat"
|
||||
msgid "archived"
|
||||
msgstr "archivé"
|
||||
|
||||
#: counter/models.py:157 counter/models.py:564
|
||||
#: counter/models.py:157 counter/models.py:566
|
||||
msgid "product"
|
||||
msgstr "produit"
|
||||
|
||||
@ -3197,7 +3201,7 @@ msgstr "vendeurs"
|
||||
msgid "token"
|
||||
msgstr "jeton"
|
||||
|
||||
#: counter/models.py:195 counter/models.py:462 counter/models.py:480
|
||||
#: counter/models.py:195 counter/models.py:464 counter/models.py:482
|
||||
#: launderette/models.py:39 stock/models.py:39
|
||||
msgid "counter"
|
||||
msgstr "comptoir"
|
||||
@ -3206,7 +3210,7 @@ msgstr "comptoir"
|
||||
msgid "bank"
|
||||
msgstr "banque"
|
||||
|
||||
#: counter/models.py:305 counter/models.py:352
|
||||
#: counter/models.py:305 counter/models.py:353
|
||||
msgid "is validated"
|
||||
msgstr "est validé"
|
||||
|
||||
@ -3214,37 +3218,37 @@ msgstr "est validé"
|
||||
msgid "refilling"
|
||||
msgstr "rechargement"
|
||||
|
||||
#: counter/models.py:345 eboutic/models.py:129
|
||||
#: counter/models.py:346 eboutic/models.py:129
|
||||
msgid "unit price"
|
||||
msgstr "prix unitaire"
|
||||
|
||||
#: counter/models.py:346 counter/models.py:553 eboutic/models.py:130
|
||||
#: counter/models.py:347 counter/models.py:555 eboutic/models.py:130
|
||||
msgid "quantity"
|
||||
msgstr "quantité"
|
||||
|
||||
#: counter/models.py:351
|
||||
#: counter/models.py:352
|
||||
msgid "Sith account"
|
||||
msgstr "Compte utilisateur"
|
||||
|
||||
#: counter/models.py:351 sith/settings.py:359 sith/settings.py:364
|
||||
#: counter/models.py:352 sith/settings.py:359 sith/settings.py:364
|
||||
#: sith/settings.py:386
|
||||
msgid "Credit card"
|
||||
msgstr "Carte bancaire"
|
||||
|
||||
#: counter/models.py:355
|
||||
#: counter/models.py:356
|
||||
msgid "selling"
|
||||
msgstr "vente"
|
||||
|
||||
#: counter/models.py:374
|
||||
#: counter/models.py:375
|
||||
msgid "Unknown event"
|
||||
msgstr "Événement inconnu"
|
||||
|
||||
#: counter/models.py:375
|
||||
#: counter/models.py:376
|
||||
#, python-format
|
||||
msgid "Eticket bought for the event %(event)s"
|
||||
msgstr "Eticket acheté pour l'événement %(event)s"
|
||||
|
||||
#: counter/models.py:377 counter/models.py:389
|
||||
#: counter/models.py:378 counter/models.py:390
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You bought an eticket for the event %(event)s.\n"
|
||||
@ -3253,51 +3257,51 @@ msgstr ""
|
||||
"Vous avez acheté un Eticket pour l'événement %(event)s.\n"
|
||||
"Vous pouvez le télécharger sur cette page: %(url)s"
|
||||
|
||||
#: counter/models.py:465
|
||||
#: counter/models.py:467
|
||||
msgid "last activity date"
|
||||
msgstr "dernière activité"
|
||||
|
||||
#: counter/models.py:468
|
||||
#: counter/models.py:470
|
||||
msgid "permanency"
|
||||
msgstr "permanence"
|
||||
|
||||
#: counter/models.py:483
|
||||
#: counter/models.py:485
|
||||
msgid "emptied"
|
||||
msgstr "coffre vidée"
|
||||
|
||||
#: counter/models.py:486
|
||||
#: counter/models.py:488
|
||||
msgid "cash register summary"
|
||||
msgstr "relevé de caisse"
|
||||
|
||||
#: counter/models.py:551
|
||||
#: counter/models.py:553
|
||||
msgid "cash summary"
|
||||
msgstr "relevé"
|
||||
|
||||
#: counter/models.py:552
|
||||
#: counter/models.py:554
|
||||
msgid "value"
|
||||
msgstr "valeur"
|
||||
|
||||
#: counter/models.py:554
|
||||
#: counter/models.py:556
|
||||
msgid "check"
|
||||
msgstr "chèque"
|
||||
|
||||
#: counter/models.py:557
|
||||
#: counter/models.py:559
|
||||
msgid "cash register summary item"
|
||||
msgstr "élément de relevé de caisse"
|
||||
|
||||
#: counter/models.py:565
|
||||
#: counter/models.py:567
|
||||
msgid "banner"
|
||||
msgstr "bannière"
|
||||
|
||||
#: counter/models.py:566
|
||||
#: counter/models.py:568
|
||||
msgid "event date"
|
||||
msgstr "date de l'événement"
|
||||
|
||||
#: counter/models.py:567
|
||||
#: counter/models.py:569
|
||||
msgid "event title"
|
||||
msgstr "titre de l'événement"
|
||||
|
||||
#: counter/models.py:568
|
||||
#: counter/models.py:570
|
||||
msgid "secret"
|
||||
msgstr "secret"
|
||||
|
||||
@ -5053,6 +5057,9 @@ msgstr "Vous ne pouvez plus écrire de commentaires, la date est passée."
|
||||
msgid "Maximum characters: %(max_length)s"
|
||||
msgstr "Nombre de caractères max: %(max_length)s"
|
||||
|
||||
#~ msgid "define if we show a users stats"
|
||||
#~ msgstr "Definit si l'on montre les statistiques de l'utilisateur"
|
||||
|
||||
#~ msgid "General management"
|
||||
#~ msgstr "Gestion générale"
|
||||
|
||||
|
19
subscription/migrations/0006_auto_20170902_1222.py
Normal file
19
subscription/migrations/0006_auto_20170902_1222.py
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('subscription', '0005_auto_20170821_2054'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='subscription',
|
||||
name='subscription_type',
|
||||
field=models.CharField(verbose_name='subscription type', choices=[('amicale/doceo', 'Amicale/DOCEO member'), ('assidu', 'Assidu member'), ('crous', 'CROUS member'), ('cursus-alternant', 'Alternating cursus'), ('cursus-branche', 'Branch cursus'), ('cursus-tronc-commun', 'Common core cursus'), ('deux-mois-essai', 'Two month for free'), ('deux-semestres', 'Two semesters'), ('membre-honoraire', 'Honorary member'), ('reseau-ut', 'UT network member'), ('sbarro/esta', 'Sbarro/ESTA member'), ('un-semestre', 'One semester'), ('un-semestre-welcome', 'One semester Welcome Week')], max_length=255),
|
||||
),
|
||||
]
|
Loading…
Reference in New Issue
Block a user