Nouvelle orientation du projet, redéfinition des structures de données.
This commit is contained in:
parent
be45b37ed4
commit
b5a51e1bec
19 changed files with 141 additions and 350 deletions
|
@ -1,5 +1,6 @@
|
||||||
# Generated by Django 2.0.1 on 2018-02-28 18:43
|
# Generated by Django 2.0.1 on 2018-03-08 22:03
|
||||||
|
|
||||||
|
import content.models
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
('users', '0001_initial'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -26,8 +28,9 @@ class Migration(migrations.Migration):
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('name', models.CharField(max_length=255, verbose_name='Nom du contenu')),
|
('name', models.CharField(max_length=255, verbose_name='Nom du contenu')),
|
||||||
('file', models.FileField(upload_to='', verbose_name='Fichier')),
|
('file', models.FileField(upload_to=content.models.get_upload_to, validators=[content.models.validate_file_extension], verbose_name='Fichier')),
|
||||||
('category', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='content.Category', verbose_name='Catégorie')),
|
('category', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='content.Category', verbose_name='Catégorie')),
|
||||||
|
('school_owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.School')),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
# Generated by Django 2.0.1 on 2018-02-28 18:43
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
initial = True
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('content', '0001_initial'),
|
|
||||||
('users', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='content',
|
|
||||||
name='school_owner',
|
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.SchoolProfile'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,9 +1,11 @@
|
||||||
from django.db import models
|
import os
|
||||||
from django.urls import reverse
|
|
||||||
from django.contrib.auth.models import Group
|
from django.db import models
|
||||||
from django.conf import settings
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from users.models import School
|
||||||
|
|
||||||
from users.models import SchoolProfile
|
|
||||||
|
|
||||||
class Category(models.Model):
|
class Category(models.Model):
|
||||||
"""Une catégorie de contenu."""
|
"""Une catégorie de contenu."""
|
||||||
|
@ -19,13 +21,26 @@ class Category(models.Model):
|
||||||
verbose_name="Illustration de la catégorie",
|
verbose_name="Illustration de la catégorie",
|
||||||
null=True,
|
null=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('content:category-list', kwargs={'pk':self.pk})
|
return reverse('content:category-list', kwargs={'pk': self.pk})
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
def get_upload_to(instance, filename):
|
||||||
|
extension = filename.split('.')[-1]
|
||||||
|
return "static/media/"+instance.school.name+"/"+instance.category.name+'.'+extension
|
||||||
|
|
||||||
|
|
||||||
|
def validate_file_extension(value):
|
||||||
|
ext = os.path.splitext(value.name)[1] # [0] returns path+filename
|
||||||
|
valid_extensions = ['mp4', 'avi', 'mov']
|
||||||
|
if not ext.lower() in valid_extensions:
|
||||||
|
raise ValidationError(u'Unsupported file extension.')
|
||||||
|
|
||||||
|
|
||||||
class Content(models.Model):
|
class Content(models.Model):
|
||||||
"""Un contenu du site (vidéo)."""
|
"""Un contenu du site (vidéo)."""
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
|
@ -33,7 +48,7 @@ class Content(models.Model):
|
||||||
verbose_name="Nom du contenu"
|
verbose_name="Nom du contenu"
|
||||||
)
|
)
|
||||||
school_owner = models.ForeignKey(
|
school_owner = models.ForeignKey(
|
||||||
SchoolProfile,
|
School,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
)
|
)
|
||||||
category = models.ForeignKey(
|
category = models.ForeignKey(
|
||||||
|
@ -43,11 +58,10 @@ class Content(models.Model):
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
file = models.FileField(
|
file = models.FileField(
|
||||||
verbose_name="Fichier"
|
verbose_name="Fichier",
|
||||||
|
validators=[validate_file_extension],
|
||||||
|
upload_to=get_upload_to
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def manager_right(self):
|
|
||||||
return 'users.manage_' + str(self.school_owner.group.pk)
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 2.0.1 on 2018-02-28 18:43
|
# Generated by Django 2.0.1 on 2018-03-08 22:03
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
@ -17,6 +17,16 @@ class Migration(migrations.Migration):
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('allow_upload', models.BooleanField(default=False, verbose_name="Autoriser l'upload de vidéos.")),
|
('allow_upload', models.BooleanField(default=False, verbose_name="Autoriser l'upload de vidéos.")),
|
||||||
('home_message', models.TextField(default='', verbose_name="Message de la page d'accueil")),
|
('home_message', models.TextField(default='', verbose_name="Message de la page d'accueil")),
|
||||||
|
('site_logo', models.ImageField(blank=True, null=True, upload_to='', verbose_name='Logo du site')),
|
||||||
|
('event_poster', models.ImageField(blank=True, null=True, upload_to='', verbose_name="Affiche de l'événement")),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='StaticPage',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='Titre de la catégorie')),
|
||||||
|
('text', models.TextField(verbose_name='Texte de la catégorie')),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
# Generated by Django 2.0.1 on 2018-03-01 10:47
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('settings', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='sitesettings',
|
|
||||||
name='event_poster',
|
|
||||||
field=models.ImageField(null=True, upload_to='', verbose_name="Affiche de l'événement"),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='sitesettings',
|
|
||||||
name='min_number_of_categories',
|
|
||||||
field=models.PositiveIntegerField(default=0, verbose_name='Nombre minimal de catégories dans laquelle participer'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='sitesettings',
|
|
||||||
name='site_logo',
|
|
||||||
field=models.ImageField(null=True, upload_to='', verbose_name='Logo du site'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,23 +0,0 @@
|
||||||
# Generated by Django 2.0.1 on 2018-03-01 11:09
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('settings', '0002_auto_20180301_1047'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='sitesettings',
|
|
||||||
name='event_poster',
|
|
||||||
field=models.ImageField(blank=True, null=True, upload_to='', verbose_name="Affiche de l'événement"),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='sitesettings',
|
|
||||||
name='site_logo',
|
|
||||||
field=models.ImageField(blank=True, null=True, upload_to='', verbose_name='Logo du site'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,7 +1,5 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from .aes_field import AESEncryptedField
|
|
||||||
|
|
||||||
|
|
||||||
class SiteSettings(models.Model):
|
class SiteSettings(models.Model):
|
||||||
PRETTY_NAME = "Réglages du site"
|
PRETTY_NAME = "Réglages du site"
|
||||||
|
@ -23,11 +21,17 @@ class SiteSettings(models.Model):
|
||||||
null=True,
|
null=True,
|
||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
min_number_of_categories = models.PositiveIntegerField(
|
|
||||||
verbose_name="Nombre minimal de catégories dans laquelle participer",
|
|
||||||
default=0,
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_settings(cls):
|
def get_settings(cls):
|
||||||
return cls.objects.get_or_create()[0]
|
return cls.objects.get_or_create()[0]
|
||||||
|
|
||||||
|
|
||||||
|
class StaticPage(models.Model):
|
||||||
|
name = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="Titre de la catégorie",
|
||||||
|
)
|
||||||
|
text = models.TextField(
|
||||||
|
verbose_name="Texte de la catégorie"
|
||||||
|
)
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
|
||||||
from content.models import Category
|
from content.models import Category
|
||||||
from users.models import SchoolProfile
|
from users.models import School
|
||||||
from .models import SiteSettings
|
from .models import SiteSettings
|
||||||
from .forms import SelectUserForm
|
from .forms import SelectUserForm
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ class SettingsView(LoginRequiredMixin, PermissionRequiredMixin, TemplateView):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context['categories'] = Category.objects.all()
|
context['categories'] = Category.objects.all()
|
||||||
context['site_settings'], _ = SiteSettings.objects.get_or_create()
|
context['site_settings'], _ = SiteSettings.objects.get_or_create()
|
||||||
context['schools'] = SchoolProfile.objects.all()
|
context['schools'] = School.objects.all()
|
||||||
context['settings'] = True
|
context['settings'] = True
|
||||||
context['administrators'] = Group.objects.get(name='admins').user_set.all()
|
context['administrators'] = Group.objects.get(name='admins').user_set.all()
|
||||||
return context
|
return context
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
"""
|
|
||||||
WSGI config for site_tps project.
|
|
||||||
|
|
||||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
|
||||||
|
|
||||||
For more information on this file, see
|
|
||||||
https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
VIRTUALENV_LOC = '/var/www/site_tps/env_site'
|
||||||
|
|
||||||
|
# Activation de l'environnement virtuel
|
||||||
|
activate_env=os.path.join(VIRTUALENV_LOC, 'bin/activate_this.py')
|
||||||
|
exec(compile(open(activate_env, "rb").read(), activate_env, 'exec'), {'__file__':activate_env})
|
||||||
|
|
||||||
|
# Ajout du répertoire du site au PATH
|
||||||
|
sys.path.append('/var/www/site_tps')
|
||||||
|
sys.path.append('/var/www/site_tps/site_tps')
|
||||||
|
|
||||||
|
# Les trucs par défaut de Django
|
||||||
from django.core.wsgi import get_wsgi_application
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "site_tps.settings")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "site_tps.settings")
|
||||||
|
|
||||||
application = get_wsgi_application()
|
application = get_wsgi_application()
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
from django.contrib import admin
|
|
||||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
|
||||||
from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
|
|
||||||
from django.contrib.auth.models import User, Group
|
|
||||||
|
|
||||||
from .models import UserProfile, SchoolProfile
|
|
||||||
|
|
||||||
# Define an inline admin descriptor for Employee model
|
|
||||||
# which acts a bit like a singleton
|
|
||||||
|
|
||||||
|
|
||||||
class UserInline(admin.StackedInline):
|
|
||||||
model = UserProfile
|
|
||||||
can_delete = False
|
|
||||||
verbose_name_plural = 'user profiles'
|
|
||||||
|
|
||||||
# Define a new User admin
|
|
||||||
|
|
||||||
|
|
||||||
class UserAdmin(BaseUserAdmin):
|
|
||||||
inlines = (UserInline, )
|
|
||||||
|
|
||||||
# Define an inline admin descriptor for Employee model
|
|
||||||
# which acts a bit like a singleton
|
|
||||||
|
|
||||||
|
|
||||||
class SchoolInline(admin.StackedInline):
|
|
||||||
model = SchoolProfile
|
|
||||||
can_delete = False
|
|
||||||
verbose_name_plural = 'schools'
|
|
||||||
fk_name = 'admins'
|
|
||||||
|
|
||||||
# Define a new User admin
|
|
||||||
|
|
||||||
|
|
||||||
class GroupAdmin(BaseGroupAdmin):
|
|
||||||
inlines = (SchoolInline, )
|
|
||||||
|
|
||||||
|
|
||||||
# Re-register UserAdmin
|
|
||||||
admin.site.unregister(User)
|
|
||||||
admin.site.register(User, UserAdmin)
|
|
||||||
admin.site.unregister(Group)
|
|
||||||
admin.site.register(Group, GroupAdmin)
|
|
|
@ -1,8 +1,10 @@
|
||||||
# Generated by Django 2.0.1 on 2018-02-28 18:43
|
# Generated by Django 2.0.1 on 2018-03-08 22:03
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
import django.core.validators
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
import users.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -10,24 +12,25 @@ class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('auth', '0009_alter_user_last_name_max_length'),
|
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='SchoolProfile',
|
name='School',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='students', to='auth.Group')),
|
('phone', models.CharField(help_text='Visible uniquement des administrateurs', max_length=10, null=True, validators=[django.core.validators.RegexValidator('^[0-9]{10}$', 'Veuillez entrer un numéro à 10 chiffres.')], verbose_name='Numéro de téléphone pour contacter le responsable des productions')),
|
||||||
],
|
('logo', models.ImageField(null=True, upload_to=users.models.get_upload_to, verbose_name="Logo à utiliser pour représenter l'école")),
|
||||||
),
|
('first_name_j1', models.CharField(max_length=255, verbose_name='Prénom juré n°1')),
|
||||||
migrations.CreateModel(
|
('last_name_j1', models.CharField(max_length=255, verbose_name='Nom juré n°1')),
|
||||||
name='UserProfile',
|
('phone_j1', models.CharField(help_text='Visible uniquement des administrateurs', max_length=10, null=True, validators=[django.core.validators.RegexValidator('^[0-9]{10}$', 'Veuillez entrer un numéro à 10 chiffres.')], verbose_name='Numéro de téléphone juré n°1')),
|
||||||
fields=[
|
('mail_j1', models.EmailField(max_length=254, verbose_name='Email juré n°1')),
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('first_name_j2', models.CharField(max_length=255, verbose_name='Prénom juré n°2')),
|
||||||
('school', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.SchoolProfile')),
|
('last_name_j2', models.CharField(max_length=255, verbose_name='Nom juré n°2')),
|
||||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
('phone_j2', models.CharField(help_text='Visible uniquement des administrateurs', max_length=10, null=True, validators=[django.core.validators.RegexValidator('^[0-9]{10}$', 'Veuillez entrer un numéro à 10 chiffres.')], verbose_name='Numéro de téléphone juré n°2')),
|
||||||
|
('mail_j2', models.EmailField(max_length=254, verbose_name='Email juré n°2')),
|
||||||
|
('admin', models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name="Administrateur de l'école")),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
# Generated by Django 2.0.1 on 2018-03-01 07:16
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('auth', '0009_alter_user_last_name_max_length'),
|
|
||||||
('users', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='schoolprofile',
|
|
||||||
name='admins',
|
|
||||||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='admin_of', to='auth.Group'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,19 +0,0 @@
|
||||||
# Generated by Django 2.0.1 on 2018-03-01 09:33
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('users', '0002_schoolprofile_admins'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='schoolprofile',
|
|
||||||
name='group',
|
|
||||||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='school', to='auth.Group'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,19 +0,0 @@
|
||||||
# Generated by Django 2.0.1 on 2018-03-01 09:52
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('users', '0003_auto_20180301_0933'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='schoolprofile',
|
|
||||||
name='group',
|
|
||||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='school', to='auth.Group'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,19 +0,0 @@
|
||||||
# Generated by Django 2.0.1 on 2018-03-01 10:29
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('users', '0004_auto_20180301_0952'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='userprofile',
|
|
||||||
name='school',
|
|
||||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.SchoolProfile'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Generated by Django 2.0.1 on 2018-03-01 23:28
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('users', '0005_auto_20180301_1029'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='schoolprofile',
|
|
||||||
name='phone',
|
|
||||||
field=models.CharField(help_text='Visible uniquement des administrateurs', max_length=10, null=True, verbose_name='Numéro de téléphone pour contacter le responsable des productions'),
|
|
||||||
),
|
|
||||||
]
|
|
118
users/models.py
118
users/models.py
|
@ -7,18 +7,17 @@ from django.dispatch import receiver
|
||||||
from django.core import validators
|
from django.core import validators
|
||||||
|
|
||||||
|
|
||||||
class SchoolProfile(models.Model):
|
def get_upload_to(instance, filename):
|
||||||
|
return "static/media/"+instance.name+"/"+filename
|
||||||
|
|
||||||
|
|
||||||
|
class School(models.Model):
|
||||||
"""Ajoute un champ pour distinguer les groupes écoles des autres."""
|
"""Ajoute un champ pour distinguer les groupes écoles des autres."""
|
||||||
group = models.OneToOneField(
|
admin = models.OneToOneField(
|
||||||
Group,
|
User,
|
||||||
on_delete=models.CASCADE,
|
verbose_name="Administrateur de l'école",
|
||||||
related_name="school",
|
null=True,
|
||||||
)
|
|
||||||
admins = models.OneToOneField(
|
|
||||||
Group,
|
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
related_name="admin_of",
|
|
||||||
null=True
|
|
||||||
)
|
)
|
||||||
phone = models.CharField(
|
phone = models.CharField(
|
||||||
max_length=10,
|
max_length=10,
|
||||||
|
@ -31,6 +30,53 @@ class SchoolProfile(models.Model):
|
||||||
"Veuillez entrer un numéro à 10 chiffres."),
|
"Veuillez entrer un numéro à 10 chiffres."),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
logo = models.ImageField(
|
||||||
|
upload_to=get_upload_to,
|
||||||
|
verbose_name="Logo à utiliser pour représenter l'école",
|
||||||
|
null=True,
|
||||||
|
blank=False,
|
||||||
|
)
|
||||||
|
first_name_j1 = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="Prénom juré n°1"
|
||||||
|
)
|
||||||
|
last_name_j1 = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="Nom juré n°1"
|
||||||
|
)
|
||||||
|
phone_j1 = models.CharField(
|
||||||
|
max_length=10,
|
||||||
|
help_text="Visible uniquement des administrateurs",
|
||||||
|
verbose_name="Numéro de téléphone juré n°1",
|
||||||
|
blank=False,
|
||||||
|
null=True,
|
||||||
|
validators=[
|
||||||
|
validators.RegexValidator('^[0-9]{10}$',
|
||||||
|
"Veuillez entrer un numéro à 10 chiffres."),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
mail_j1 = models.EmailField(verbose_name="Email juré n°1")
|
||||||
|
first_name_j2 = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="Prénom juré n°2"
|
||||||
|
)
|
||||||
|
last_name_j2 = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="Nom juré n°2"
|
||||||
|
)
|
||||||
|
phone_j2 = models.CharField(
|
||||||
|
max_length=10,
|
||||||
|
help_text="Visible uniquement des administrateurs",
|
||||||
|
verbose_name="Numéro de téléphone juré n°2",
|
||||||
|
blank=False,
|
||||||
|
null=True,
|
||||||
|
validators=[
|
||||||
|
validators.RegexValidator('^[0-9]{10}$',
|
||||||
|
"Veuillez entrer un numéro à 10 chiffres."),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
mail_j2 = models.EmailField(verbose_name="Email juré n°2")
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.group.name
|
return self.group.name
|
||||||
|
@ -41,55 +87,3 @@ class SchoolProfile(models.Model):
|
||||||
def number_of_categories(self):
|
def number_of_categories(self):
|
||||||
return self.content_set.values('category').distinct().count()
|
return self.content_set.values('category').distinct().count()
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
viewing_right, _ = Permission.objects.get_or_create(
|
|
||||||
codename='view_' + str(self.group.pk),
|
|
||||||
name='Peut voir ' + str(self.group.pk),
|
|
||||||
content_type=ContentType.objects.get_for_model(SchoolProfile)
|
|
||||||
)
|
|
||||||
if viewing_right not in self.group.permissions.all():
|
|
||||||
self.group.permissions.add(viewing_right)
|
|
||||||
self.group.save()
|
|
||||||
admins,_ = Group.objects.get_or_create(name='admins')
|
|
||||||
admins.permissions.add(viewing_right)
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=SchoolProfile)
|
|
||||||
def update_permissions_school(sender, instance, **kwargs):
|
|
||||||
instance.admins,admin_created = Group.objects.get_or_create(name=str(instance.group.pk)+'_admins')
|
|
||||||
admin_right,_ = Permission.objects.get_or_create(
|
|
||||||
codename='manage_' + str(instance.group.pk),
|
|
||||||
name="Administrateur de l'école " + str(instance.group.pk),
|
|
||||||
content_type=ContentType.objects.get_for_model(SchoolProfile)
|
|
||||||
)
|
|
||||||
admins,_ = Group.objects.get_or_create(name='admins')
|
|
||||||
admins.permissions.add(admin_right)
|
|
||||||
if admin_created:
|
|
||||||
instance.save(update_fields=['admins'])
|
|
||||||
instance.admins.permissions.add(admin_right)
|
|
||||||
instance.admins.save()
|
|
||||||
|
|
||||||
|
|
||||||
class UserProfile(models.Model):
|
|
||||||
"""Profil d'un utilisateur"""
|
|
||||||
school = models.ForeignKey(SchoolProfile, on_delete=models.SET_NULL, null=True)
|
|
||||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=UserProfile)
|
|
||||||
def update_groups(sender, instance, **kwargs):
|
|
||||||
instance.user.groups.add(instance.school.group)
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=User)
|
|
||||||
def update_permission_user(sender, instance, **kwargs):
|
|
||||||
perm,_ = Permission.objects.get_or_create(
|
|
||||||
codename='manage_'+str(instance.pk),
|
|
||||||
name='Peut administrer ' + instance.username,
|
|
||||||
content_type=ContentType.objects.get_for_model(User)
|
|
||||||
)
|
|
||||||
instance.user_permissions.add(perm)
|
|
||||||
admins,_ = Group.objects.get_or_create(name='admins')
|
|
||||||
admins.permissions.add(perm)
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from .views import (
|
from .views import (
|
||||||
CreateUser,
|
CreateUser,
|
||||||
CreateUserProfile,
|
|
||||||
CreateSchool,
|
CreateSchool,
|
||||||
EditSchoolName,
|
EditSchoolName,
|
||||||
EditSchoolPhone,
|
EditSchoolPhone,
|
||||||
|
@ -37,11 +36,6 @@ urlpatterns = [
|
||||||
PasswordChange.as_view(),
|
PasswordChange.as_view(),
|
||||||
name='change-password'
|
name='change-password'
|
||||||
),
|
),
|
||||||
path(
|
|
||||||
'user/<int:pk>/set_school',
|
|
||||||
CreateUserProfile.as_view(),
|
|
||||||
name='create-userprofile'
|
|
||||||
),
|
|
||||||
path(
|
path(
|
||||||
'user/<int:pk>',
|
'user/<int:pk>',
|
||||||
Profile.as_view(),
|
Profile.as_view(),
|
||||||
|
|
|
@ -8,7 +8,7 @@ from django.contrib import messages
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.shortcuts import get_object_or_404, redirect
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
|
|
||||||
from .models import UserProfile, SchoolProfile
|
from .models import School
|
||||||
from content.models import Content
|
from content.models import Content
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,27 +64,9 @@ class Profile(LoginRequiredMixin, UpdateView):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class CreateUserProfile(CreateView):
|
|
||||||
model = UserProfile
|
|
||||||
fields = ['school']
|
|
||||||
template_name = 'edit.html'
|
|
||||||
|
|
||||||
success_url = reverse_lazy('home')
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
context['title'] = "Choix de l'école"
|
|
||||||
context['validate'] = "Choisir"
|
|
||||||
return context
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
form.instance.user = get_object_or_404(User, pk=self.kwargs['pk'])
|
|
||||||
return super(CreateUserProfile, self).form_valid(form)
|
|
||||||
|
|
||||||
|
|
||||||
class CreateSchool(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
|
class CreateSchool(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
|
||||||
permission_required = 'users.add_schoolprofile'
|
permission_required = 'users.add_schoolprofile'
|
||||||
model = Group
|
model = School
|
||||||
fields = ['name']
|
fields = ['name']
|
||||||
template_name = 'edit.html'
|
template_name = 'edit.html'
|
||||||
success_url = reverse_lazy('settings:index')
|
success_url = reverse_lazy('settings:index')
|
||||||
|
@ -97,17 +79,16 @@ class CreateSchool(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
response = super(CreateSchool, self).form_valid(form)
|
response = super(CreateSchool, self).form_valid(form)
|
||||||
profile = SchoolProfile()
|
profile = School()
|
||||||
profile.group = form.instance
|
profile.group = form.instance
|
||||||
profile.save()
|
profile.save()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
class EditSchoolName(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
|
class EditSchoolName(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
|
||||||
model = Group
|
model = School
|
||||||
fields = ['name']
|
fields = ['name']
|
||||||
template_name = 'edit.html'
|
template_name = 'edit.html'
|
||||||
queryset = Group.objects.filter(school__isnull=False)
|
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse('users:edit-school-phone', kwargs={'pk':self.object.school.pk})
|
return reverse('users:edit-school-phone', kwargs={'pk':self.object.school.pk})
|
||||||
|
@ -128,7 +109,7 @@ class EditSchoolName(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
|
||||||
|
|
||||||
|
|
||||||
class EditSchoolPhone(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
|
class EditSchoolPhone(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
|
||||||
model = SchoolProfile
|
model = School
|
||||||
fields = ['phone']
|
fields = ['phone']
|
||||||
template_name = 'edit.html'
|
template_name = 'edit.html'
|
||||||
|
|
||||||
|
@ -148,13 +129,11 @@ class EditSchoolPhone(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
|
||||||
class DeleteSchool(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
|
class DeleteSchool(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
|
||||||
model = Group
|
model = Group
|
||||||
permission_required = 'users.delete_schoolprofile'
|
permission_required = 'users.delete_schoolprofile'
|
||||||
queryset = Group.objects.filter(school__isnull=False)
|
|
||||||
|
|
||||||
|
|
||||||
class School(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
class School(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
||||||
model = Group
|
model = Group
|
||||||
template_name = "users/school.html"
|
template_name = "users/school.html"
|
||||||
queryset = Group.objects.filter(school__isnull=False)
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data()
|
context = super().get_context_data()
|
||||||
|
|
Loading…
Reference in a new issue