1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-06-28 20:33:00 +02:00

Not so atomic, sorry

This commit is contained in:
Alexandre Iooss
2019-07-16 12:43:23 +02:00
parent ab616b3f64
commit fbe2e7f59a
30 changed files with 885 additions and 332 deletions

5
member/__init__.py Normal file
View File

@ -0,0 +1,5 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'member.apps.MemberConfig'

37
member/admin.py Normal file
View File

@ -0,0 +1,37 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from .forms import CustomUserChangeForm
from .models import Profile
class ProfileInline(admin.StackedInline):
"""
Inline user profile in user admin
"""
model = Profile
can_delete = False
class CustomUserAdmin(UserAdmin):
inlines = (ProfileInline,)
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
list_select_related = ('profile',)
form = CustomUserChangeForm
def get_inline_instances(self, request, obj=None):
"""
When creating a new user don't show profile one the first step
"""
if not obj:
return list()
return super().get_inline_instances(request, obj)
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)

11
member/apps.py Normal file
View File

@ -0,0 +1,11 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class MemberConfig(AppConfig):
name = 'member'
verbose_name = _('member')

17
member/forms.py Normal file
View File

@ -0,0 +1,17 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib.auth.forms import UserChangeForm
class CustomUserChangeForm(UserChangeForm):
"""
Make first name, last name and email required
in the default Django Auth User model
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['first_name'].required = True
self.fields['last_name'].required = True
self.fields['email'].required = True

View File

@ -0,0 +1,119 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-16 12:37+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: apps.py:11
msgid "member"
msgstr "adhérent"
#: models.py:24
msgid "profile picture"
msgstr "image de profil"
#: models.py:29
msgid "phone number"
msgstr "numéro de téléphone"
#: models.py:36
msgid "section"
msgstr "section"
#: models.py:37
msgid "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
msgstr "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
#: models.py:41
msgid "address"
msgstr "adresse"
#: models.py:47 models.py:61
msgid "paid"
msgstr "payé"
#: models.py:52 models.py:53
msgid "user profile"
msgstr "profil utilisateur"
#: models.py:65
msgid "email"
msgstr "courriel"
#: models.py:70
msgid "membership fee"
msgstr "cotisation"
#: models.py:74
msgid "membership duration"
msgstr "durée de l'adhésion"
#: models.py:75
msgid "The longest time a membership can last (NULL = infinite)."
msgstr "La durée maximale d'une adhésion (NULL = infinie)."
#: models.py:79
msgid "membership start"
msgstr "début de l'adhésion"
#: models.py:80
msgid "How long after January 1st the members can renew their membership."
msgstr ""
#: models.py:84
msgid "membership end"
msgstr "fin de l'adhésion"
#: models.py:85
msgid ""
"How long the membership can last after January 1st of the next year after "
"members can renew their membership."
msgstr ""
#: models.py:95
msgid "name"
msgstr "nom"
#: models.py:100
msgid "role"
msgstr "rôle"
#: models.py:101
msgid "roles"
msgstr "rôles"
#: models.py:118
msgid "membership starts on"
msgstr "l'adhésion commence le"
#: models.py:121
#, fuzzy
#| msgid "membership fees"
msgid "membership ends on"
msgstr "l'adhésion finie le"
#: models.py:125
msgid "fee"
msgstr "cotisation"
#: models.py:129
msgid "membership"
msgstr "adhésion"
#: models.py:130
msgid "memberships"
msgstr "adhésions"

View File

@ -0,0 +1,72 @@
# Generated by Django 2.2.3 on 2019-07-16 10:33
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Club',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='paid')),
('email', models.EmailField(max_length=254, verbose_name='email')),
('membership_fee', models.PositiveIntegerField(verbose_name='membership fee')),
('membership_duration', models.DurationField(help_text='The longest time a membership can last (NULL = infinite).', null=True, verbose_name='membership duration')),
('membership_start', models.DurationField(help_text='How long after January 1st the members can renew their membership.', null=True, verbose_name='membership start')),
('membership_end', models.DurationField(help_text='How long the membership can last after January 1st of the next year after members can renew their membership.', null=True, verbose_name='membership end')),
],
),
migrations.CreateModel(
name='Role',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='name')),
],
options={
'verbose_name': 'role',
'verbose_name_plural': 'roles',
},
),
migrations.CreateModel(
name='Profile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('profile_picture', models.ImageField(blank=True, max_length=255, upload_to='', verbose_name='profile picture')),
('phone_number', models.CharField(blank=True, default='', max_length=50, null=True, verbose_name='phone number')),
('section', models.CharField(help_text='e.g. "1A0", "9A♥", "SAPHIRE"', max_length=255, verbose_name='section')),
('address', models.CharField(blank=True, max_length=255, null=True, verbose_name='address')),
('paid', models.BooleanField(default=False, verbose_name='paid')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'user profile',
'verbose_name_plural': 'user profile',
},
),
migrations.CreateModel(
name='Membership',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date_start', models.DateField(verbose_name='membership starts on')),
('date_end', models.DateField(null=True, verbose_name='membership ends on')),
('fee', models.PositiveIntegerField(verbose_name='fee')),
('club', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='member.Club')),
('roles', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='member.Role')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'membership',
'verbose_name_plural': 'memberships',
},
),
]

View File

140
member/models.py Normal file
View File

@ -0,0 +1,140 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
class Profile(models.Model):
"""
An user profile
We do not want to patch the Django Contrib Auth User class
so this model add an user profile with additional information.
"""
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
profile_picture = models.ImageField(
verbose_name=_('profile picture'),
max_length=255,
blank=True,
)
phone_number = models.CharField(
verbose_name=_('phone number'),
max_length=50,
blank=True,
null=True,
default='',
)
section = models.CharField(
verbose_name=_('section'),
help_text=_('e.g. "1A0", "9A♥", "SAPHIRE"'),
max_length=255,
)
address = models.CharField(
verbose_name=_('address'),
max_length=255,
blank=True,
null=True,
)
paid = models.BooleanField(
verbose_name=_("paid"),
default=False,
)
class Meta:
verbose_name = _('user profile')
verbose_name_plural = _('user profile')
class Club(models.Model):
"""
A student club
"""
name = models.CharField(
verbose_name=_('paid'),
max_length=255,
)
email = models.EmailField(
verbose_name=_('email'),
)
# Memberships
membership_fee = models.PositiveIntegerField(
verbose_name=_('membership fee'),
)
membership_duration = models.DurationField(
null=True,
verbose_name=_('membership duration'),
help_text=_('The longest time a membership can last (NULL = infinite).'),
)
membership_start = models.DurationField(
null=True,
verbose_name=_('membership start'),
help_text=_('How long after January 1st the members can renew their membership.'),
)
membership_end = models.DurationField(
null=True,
verbose_name=_('membership end'),
help_text=_('How long the membership can last after January 1st of the next year '
'after members can renew their membership.'),
)
class Role(models.Model):
"""
Role that an user can have in a club
"""
name = models.CharField(
verbose_name=_('name'),
max_length=255,
)
class Meta:
verbose_name = _('role')
verbose_name_plural = _('roles')
class Membership(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.PROTECT
)
club = models.ForeignKey(
Club,
on_delete=models.PROTECT
)
roles = models.ForeignKey(
Role,
on_delete=models.PROTECT
)
date_start = models.DateField(
verbose_name=_('membership starts on'),
)
date_end = models.DateField(
verbose_name=_('membership ends on'),
null=True,
)
fee = models.PositiveIntegerField(
verbose_name=_('fee'),
)
class Meta:
verbose_name = _('membership')
verbose_name_plural = _('memberships')
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def save_user_profile(instance, created, **_kwargs):
"""
Hook to save an user profile when an user is updated
"""
if created:
Profile.objects.create(user=instance)
instance.profile.save()

0
member/tests/__init__.py Normal file
View File