diff --git a/content/forms.py b/content/forms.py new file mode 100644 index 0000000..a8b96be --- /dev/null +++ b/content/forms.py @@ -0,0 +1,30 @@ +from django import forms + +from .models import Content, Category + + +class CreateContent(forms.ModelForm): + class Meta: + model = Content + fields = [ + 'name', + 'category', + 'file', + ] + + def __init__(self, school, *args, **kwargs): + super().__init__(*args, **kwargs) + self.instance.school = school + + already_created = map(lambda x:x.category.pk, school.content_set.select_related('category')) + self.fields['category'].queryset = Category.objects.exclude(pk__in=already_created) + + +class ContentEdit(forms.ModelForm): + class Meta: + model = Content + fields = [ + 'name', + 'file' + ] + diff --git a/content/migrations/0001_initial.py b/content/migrations/0001_initial.py index 004b326..ec520ff 100644 --- a/content/migrations/0001_initial.py +++ b/content/migrations/0001_initial.py @@ -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 import django.db.models.deletion @@ -9,6 +10,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ + ('users', '0001_initial'), ] operations = [ @@ -26,8 +28,9 @@ class Migration(migrations.Migration): fields=[ ('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')), - ('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')), + ('school_owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.School')), ], ), ] diff --git a/content/migrations/0002_auto_20180309_1116.py b/content/migrations/0002_auto_20180309_1116.py new file mode 100644 index 0000000..392f4dd --- /dev/null +++ b/content/migrations/0002_auto_20180309_1116.py @@ -0,0 +1,23 @@ +# Generated by Django 2.0.1 on 2018-03-09 10:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('content', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='category', + name='description_short', + field=models.TextField(null=True, verbose_name='Description courte'), + ), + migrations.AlterField( + model_name='category', + name='description', + field=models.TextField(default='', verbose_name='Description de la catégorie'), + ), + ] diff --git a/content/migrations/0002_content_school_owner.py b/content/migrations/0002_content_school_owner.py deleted file mode 100644 index affdd4d..0000000 --- a/content/migrations/0002_content_school_owner.py +++ /dev/null @@ -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'), - ), - ] diff --git a/content/migrations/0003_auto_20180309_1233.py b/content/migrations/0003_auto_20180309_1233.py new file mode 100644 index 0000000..43e5cce --- /dev/null +++ b/content/migrations/0003_auto_20180309_1233.py @@ -0,0 +1,19 @@ +# Generated by Django 2.0.1 on 2018-03-09 11:33 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('content', '0002_auto_20180309_1116'), + ] + + operations = [ + migrations.AlterField( + model_name='content', + name='school_owner', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='users.School'), + ), + ] diff --git a/content/migrations/0004_auto_20180309_1235.py b/content/migrations/0004_auto_20180309_1235.py new file mode 100644 index 0000000..13c8170 --- /dev/null +++ b/content/migrations/0004_auto_20180309_1235.py @@ -0,0 +1,19 @@ +# Generated by Django 2.0.1 on 2018-03-09 11:35 + +import content.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('content', '0003_auto_20180309_1233'), + ] + + operations = [ + migrations.AlterField( + model_name='content', + name='file', + field=models.FileField(upload_to=content.models.get_upload_to, verbose_name='Fichier'), + ), + ] diff --git a/content/migrations/0005_auto_20180309_1255.py b/content/migrations/0005_auto_20180309_1255.py new file mode 100644 index 0000000..e25d507 --- /dev/null +++ b/content/migrations/0005_auto_20180309_1255.py @@ -0,0 +1,18 @@ +# Generated by Django 2.0.1 on 2018-03-09 11:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('content', '0004_auto_20180309_1235'), + ] + + operations = [ + migrations.AlterField( + model_name='content', + name='file', + field=models.FileField(upload_to='', verbose_name='Fichier'), + ), + ] diff --git a/content/migrations/0006_auto_20180309_1257.py b/content/migrations/0006_auto_20180309_1257.py new file mode 100644 index 0000000..0c0febb --- /dev/null +++ b/content/migrations/0006_auto_20180309_1257.py @@ -0,0 +1,19 @@ +# Generated by Django 2.0.1 on 2018-03-09 11:57 + +import content.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('content', '0005_auto_20180309_1255'), + ] + + operations = [ + migrations.AlterField( + model_name='content', + name='file', + field=models.FileField(upload_to=content.models.get_upload_to, verbose_name='Fichier'), + ), + ] diff --git a/content/migrations/0007_auto_20180309_1315.py b/content/migrations/0007_auto_20180309_1315.py new file mode 100644 index 0000000..d006455 --- /dev/null +++ b/content/migrations/0007_auto_20180309_1315.py @@ -0,0 +1,25 @@ +# Generated by Django 2.0.1 on 2018-03-09 12:15 + +import content.models +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('content', '0006_auto_20180309_1257'), + ] + + operations = [ + migrations.AlterField( + model_name='content', + name='file', + field=models.FileField(upload_to=content.models.get_upload_to, validators=[content.models.validate_file_extension], verbose_name='Fichier'), + ), + migrations.AlterField( + model_name='content', + name='school_owner', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.School'), + ), + ] diff --git a/content/models.py b/content/models.py index 6c5b204..aa8c90b 100644 --- a/content/models.py +++ b/content/models.py @@ -1,9 +1,11 @@ -from django.db import models -from django.urls import reverse -from django.contrib.auth.models import Group -from django.conf import settings +import os + +from django.db import models +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): """Une catégorie de contenu.""" @@ -11,21 +13,40 @@ class Category(models.Model): max_length=255, verbose_name="Nom de la catégorie" ) + description_short = models.TextField( + verbose_name="Description courte", + null=True, + ) description = models.TextField( - verbose_name="Descriton de la catégorie", + verbose_name="Description de la catégorie", default="" ) image = models.ImageField( verbose_name="Illustration de la catégorie", null=True, ) + def get_absolute_url(self): - return reverse('content:category-list', kwargs={'pk':self.pk}) + return reverse('content:category', kwargs={'pk': self.pk}) def __str__(self): return self.name +def get_upload_to(instance, filename): + extension = filename.split('.')[-1] + proper_school = ''.join(e for e in instance.school_owner.name if e.isalnum() and ord(e)<128) + proper_name = ''.join(e for e in instance.category.name if e.isalnum() and ord(e)<128) + return "static/media/"+proper_school+"/"+proper_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'Format non supporté : {}'.format(ext)) + + class Content(models.Model): """Un contenu du site (vidéo).""" name = models.CharField( @@ -33,7 +54,7 @@ class Content(models.Model): verbose_name="Nom du contenu" ) school_owner = models.ForeignKey( - SchoolProfile, + School, on_delete=models.CASCADE, ) category = models.ForeignKey( @@ -43,11 +64,10 @@ class Content(models.Model): null=True ) file = models.FileField( - verbose_name="Fichier" + verbose_name="Fichier", + validators=[validate_file_extension], + upload_to=get_upload_to ) def __str__(self): return self.name - - def manager_right(self): - return 'users.manage_' + str(self.school_owner.group.pk) diff --git a/content/templates/content/content.html b/content/templates/content/content.html index 3785644..21d579d 100644 --- a/content/templates/content/content.html +++ b/content/templates/content/content.html @@ -5,15 +5,13 @@

{{content.name}}

-

Contenu proposé par {{content.school_owner.group.name}}

- {% if content.manager_right in perms %} +

Catégorie : {{content.category.name}}

- {% endif %}
diff --git a/content/templates/content/content_list.html b/content/templates/content/content_list.html index d6fb175..cc56d5b 100644 --- a/content/templates/content/content_list.html +++ b/content/templates/content/content_list.html @@ -22,15 +22,13 @@ $('html, body').animate({scrollTop: $('#category-content').offset().top}, 800);

{{category.name}}

-

{{category.description}}

+

{{category.description_short}}

Aller voir !

-
- {% for content in contents %} - {% include "content/content.html" %} - {% endfor %} +
+ {{category.description|safe}}


diff --git a/content/urls.py b/content/urls.py index ab53c2a..328bac7 100644 --- a/content/urls.py +++ b/content/urls.py @@ -1,22 +1,17 @@ from django.urls import path +from . import views + from .views import ( - ContentCategoryList, CreateCategory, + ViewCategory, DeleteCategory, EditCategory, - CreateContent, DeleteContent, - EditContent, ) app_name = 'content' urlpatterns = [ - path( - 'category//', - ContentCategoryList.as_view(), - name='category-list' - ), path( 'category/delete/', DeleteCategory.as_view(), @@ -28,13 +23,18 @@ urlpatterns = [ name='category-new' ), path( - 'category/edit/', + 'category/', + ViewCategory.as_view(), + name='category', + ), + path( + 'category//edit', EditCategory.as_view(), name='category-edit', ), path( - 'new', - CreateContent.as_view(), + 'new/', + views.create_content, name='content-new', ), path( @@ -44,7 +44,7 @@ urlpatterns = [ ), path( '/edit', - EditContent.as_view(), + views.edit_content, name="content-edit", ), diff --git a/content/views.py b/content/views.py index 0548aef..db41faa 100644 --- a/content/views.py +++ b/content/views.py @@ -1,31 +1,21 @@ from django.views import generic 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, render from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin +from django.contrib.admin.views.decorators import staff_member_required from django.contrib import messages from .models import Content, Category +from users.models import School +from . import forms from settings.models import SiteSettings -class ContentCategoryList(generic.ListView): - """Affiche les contenus d'une catégorie.""" - model = Content - context_object_name = "contents" +class ViewCategory(generic.DetailView): + """Affiche une catégorie.""" + model = Category template_name = "content/content_list.html" - def get_queryset(self): - pk = self.kwargs['pk'] - category = get_object_or_404(Category, pk=pk) - return Content.objects.filter(category=category) - - def get_context_data(self, **kwargs): - context = super(generic.ListView, self).get_context_data(**kwargs) - pk = self.kwargs['pk'] - category = get_object_or_404(Category, pk=pk) - context['category'] = category - return context - class CreateCategory(PermissionRequiredMixin, generic.CreateView): """Création de catégorie.""" @@ -60,39 +50,6 @@ class EditCategory(PermissionRequiredMixin, generic.UpdateView): return context -class CreateContent(PermissionRequiredMixin, generic.CreateView): - """Création de contenu.""" - model = Content - fields = [ - 'name', - 'category', - 'file' - ] - template_name = "edit.html" - extra_context = { - 'title' : 'Envoi de contenu', - 'validate' : 'Envoyer' - } - - def has_permission(self): - return self.request.user.has_perm('users.manage_'+str(self.request.user.userprofile.school.group.pk)) - - def get_success_url(self): - return self.object.school_owner.get_absolute_url() - - def form_valid(self, form): - form.instance.school_owner = self.request.user.userprofile.school - r = super().form_valid(form) - return r - - def dispatch(self, request, *args, **kwargs): - settings,_ = SiteSettings.objects.get_or_create() - if not settings.allow_upload : - messages.error(request, "Le téléversement de contenu n'est pas autorisé actuellement.") - return redirect(reverse("home")) - return super().dispatch(request, *args, **kwargs) - - class DeleteContent(PermissionRequiredMixin, generic.DeleteView): """Suppression de contenu""" model = Content @@ -103,34 +60,53 @@ class DeleteContent(PermissionRequiredMixin, generic.DeleteView): def has_permission(self): school = get_object_or_404(Content, pk=self.kwargs['pk']).school_owner - return self.request.user.has_perm('users.manage_'+str(school.group.pk)) + return self.request.user.is_staff or self.request.user == school.admin -class EditContent(PermissionRequiredMixin, generic.UpdateView): - """Édition d'un contenu""" - model = Content - template_name = "edit.html" - fields = [ - 'name', - 'category', - 'file' - ] - template_name = "edit.html" - extra_context = { - 'title' : 'Édition de contenu', - 'validate' : 'Envoyer' - } +def create_content(request, school_pk): + settings,_ = SiteSettings.objects.get_or_create() + if not settings.allow_upload : + messages.error(request, "Le téléversement de contenu n'est pas autorisé actuellement.") + return redirect(reverse("home")) + school = get_object_or_404(School, pk=school_pk) + can = request.user.is_staff or request.user == school.admin + if not can: + messages.error(request, 'Vous ne pouvez pas accéder à cette page') + return redirect(reverse('home')) - def get_success_url(self): - return self.object.school_owner.get_absolute_url() + content_form = forms.CreateContent(school, request.POST or None, request.FILES or None) + content_form.instance.school_owner = school - def has_permission(self): - school = get_object_or_404(Content, pk=self.kwargs['pk']).school_owner - return self.request.user.has_perm('users.manage_'+str(school.group.pk)) + if content_form.is_valid(): + content_form.save() + messages.success(request, "Contenu ajouté.") + return redirect(school.get_absolute_url()) + return render(request, 'edit.html', { + 'form' : content_form, + 'title' : 'Ajout de contenu', + 'validate' : 'Ajouter' + }) - def dispatch(self, request, *args, **kwargs): - settings,_ = SiteSettings.objects.get_or_create() - if not settings.allow_upload : - messages.error(request, "Le téléversement de contenu n'est pas autorisé actuellement.") - return redirect(reverse("home")) - return super().dispatch(request, *args, **kwargs) + +def edit_content(request, pk): + settings,_ = SiteSettings.objects.get_or_create() + if not settings.allow_upload : + messages.error(request, "Le téléversement de contenu n'est pas autorisé actuellement.") + return redirect(reverse("home")) + content = get_object_or_404(Content, pk=pk) + school = content.school_owner + can = request.user.is_staff or request.user == school.admin + if not can: + messages.error(request, 'Vous ne pouvez pas accéder à cette page') + return redirect(reverse('home')) + + content_form = forms.ContentEdit(request.POST or None, request.FILES or None, instance=content) + if content_form.is_valid(): + content_form.save() + messages.success(request, "Contenu modifié.") + return redirect(school.get_absolute_url()) + return render(request, 'edit.html', { + 'form' : content_form, + 'title' : 'Modifier un contenu', + 'validate' : 'Modifier' + }) diff --git a/settings/forms.py b/settings/forms.py index 1fc815e..aec463b 100644 --- a/settings/forms.py +++ b/settings/forms.py @@ -15,5 +15,5 @@ class SelectUserForm(forms.Form): def populate(self): admins,_ = Group.objects.get_or_create(name='admins') - choices = [(u.pk, u.first_name + ' ' + u.last_name + '(' + u.username + ')') for u in User.objects.all()] + choices = [(u.pk, u.first_name + ' ' + u.last_name + ' (' + u.username + ')') for u in User.objects.all()] self.fields['pk'].choices = choices diff --git a/settings/migrations/0001_initial.py b/settings/migrations/0001_initial.py index 035ff9e..7a5978d 100644 --- a/settings/migrations/0001_initial.py +++ b/settings/migrations/0001_initial.py @@ -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 @@ -17,6 +17,16 @@ class Migration(migrations.Migration): ('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.")), ('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')), ], ), ] diff --git a/settings/migrations/0002_auto_20180301_1047.py b/settings/migrations/0002_auto_20180301_1047.py deleted file mode 100644 index fbfe96d..0000000 --- a/settings/migrations/0002_auto_20180301_1047.py +++ /dev/null @@ -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'), - ), - ] diff --git a/settings/migrations/0003_auto_20180301_1109.py b/settings/migrations/0003_auto_20180301_1109.py deleted file mode 100644 index 417d28c..0000000 --- a/settings/migrations/0003_auto_20180301_1109.py +++ /dev/null @@ -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'), - ), - ] diff --git a/settings/models.py b/settings/models.py index 6173ce7..2376dfb 100644 --- a/settings/models.py +++ b/settings/models.py @@ -1,7 +1,5 @@ from django.db import models -from .aes_field import AESEncryptedField - class SiteSettings(models.Model): PRETTY_NAME = "Réglages du site" @@ -23,11 +21,17 @@ class SiteSettings(models.Model): null=True, blank=True ) - min_number_of_categories = models.PositiveIntegerField( - verbose_name="Nombre minimal de catégories dans laquelle participer", - default=0, - ) @classmethod def get_settings(cls): 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" + ) diff --git a/settings/templates/settings/settings.html b/settings/templates/settings/settings.html index 4c24c22..fe9cd93 100644 --- a/settings/templates/settings/settings.html +++ b/settings/templates/settings/settings.html @@ -24,7 +24,7 @@ {{admin.last_name}} {{admin.username}} - + Enlever le privilège Administrateur @@ -65,6 +65,33 @@ {% endfor %} +

Pages statiques

+ + + Créer une nouvelle page statique + +
+
+ + + + + +{% for p in static_pages %} + + + + +{% endfor %} +
Nom
{{p.name}} + + Éditer + + + + Supprimer + +

Écoles

@@ -76,30 +103,52 @@ - + + {% for school in schools %} - - + - + + {% endfor %}
NomNombre de membres Nombre de contenus Nombre de catégories Numéro de téléphoneInscriptionAdministrateur
{{school.group.name}}{{school.group.user_set.count}}{{school.name}} {{school.content_set.count}} {{school.number_of_categories}} {{school.phone}} - - Éditer - - - - Supprimer - + + {% if school.validated %} + + + Inscription validée + + {% else %} + + + Inscription non validée + + {% endif %} + + {% if school.admin %} + {{school.admin.first_name}} {{school.admin.last_name}} ({{school.admin.username}}) + {% else %} + Non défini + {% endif %} + + + + Définir +
+

Utilisateurs

+
+ + Ajouter un utilisateur +

Réglages

@@ -142,9 +191,5 @@ {% endif %} - - Nombre minimal de catégories - {{ site_settings.min_number_of_categories }} - {% endblock %} diff --git a/settings/templates/settings/static_page.html b/settings/templates/settings/static_page.html new file mode 100644 index 0000000..f81fe10 --- /dev/null +++ b/settings/templates/settings/static_page.html @@ -0,0 +1,5 @@ +{% extends "base.html" %} +{% block content %} +

{{object.name}}

+{{object.text|safe}} +{% endblock %} diff --git a/settings/templatetags/load_settings.py b/settings/templatetags/load_settings.py index e45c9b1..a1f1f6a 100644 --- a/settings/templatetags/load_settings.py +++ b/settings/templatetags/load_settings.py @@ -1,5 +1,5 @@ from django import template -from settings.models import SiteSettings +from settings.models import SiteSettings, StaticPage register = template.Library() @@ -9,7 +9,18 @@ def load_site_settings(parser, token): return LoadSiteSettingsNode() +@register.tag('load_static_pages') +def load_static_pages(parser, token): + return LoadStaticPagesNode() + + class LoadSiteSettingsNode(template.Node): def render(self, context): context['site_settings'] = SiteSettings.get_settings() return '' + + +class LoadStaticPagesNode(template.Node): + def render(self, context): + context['static_pages'] = StaticPage.objects.all() + return '' diff --git a/settings/urls.py b/settings/urls.py index 9293762..c21ba79 100644 --- a/settings/urls.py +++ b/settings/urls.py @@ -1,5 +1,5 @@ from django.urls import path -from .views import SettingsView, EditSiteSettingsView, degrade_user, promote_user +from .views import SettingsView, EditSiteSettingsView, degrade_user, promote_user, CreateStaticPageView, StaticPageView, DeleteStaticPageView, EditStaticPageView app_name = 'settings' urlpatterns = [ @@ -22,6 +22,25 @@ urlpatterns = [ 'promote_user', promote_user, name='promote-user', + ), + path( + 'static_page/new', + CreateStaticPageView.as_view(), + name='staticpage-new' + ), + path( + 'static_page/', + StaticPageView.as_view(), + name='staticpage' + ), + path( + 'static_page//delete', + DeleteStaticPageView.as_view(), + name='staticpage-delete' + ), + path( + 'static_page//edit', + EditStaticPageView.as_view(), + name='staticpage-edit' ) - ] diff --git a/settings/views.py b/settings/views.py index bd54782..7ce5dab 100644 --- a/settings/views.py +++ b/settings/views.py @@ -1,14 +1,14 @@ -from django.views.generic import TemplateView, UpdateView +from django.views.generic import TemplateView, UpdateView, CreateView, DetailView, DeleteView from django.urls import reverse_lazy, reverse from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin -from django.contrib.auth.decorators import permission_required +from django.contrib.admin.views.decorators import staff_member_required from django.contrib.auth.models import Group, User from django.shortcuts import get_object_or_404, redirect, render from django.contrib import messages from content.models import Category -from users.models import SchoolProfile -from .models import SiteSettings +from users.models import School +from .models import SiteSettings, StaticPage from .forms import SelectUserForm @@ -20,11 +20,13 @@ class SettingsView(LoginRequiredMixin, PermissionRequiredMixin, TemplateView): context = super().get_context_data(**kwargs) context['categories'] = Category.objects.all() context['site_settings'], _ = SiteSettings.objects.get_or_create() - context['schools'] = SchoolProfile.objects.all() + context['schools'] = School.objects.all() context['settings'] = True - context['administrators'] = Group.objects.get(name='admins').user_set.all() + context['administrators'] = User.objects.filter(is_staff=True) + context['static_pages'] = StaticPage.objects.all() return context + class EditSiteSettingsView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView): template_name = "edit.html" model = SiteSettings @@ -42,24 +44,82 @@ class EditSiteSettingsView(LoginRequiredMixin, PermissionRequiredMixin, UpdateVi return context -@permission_required('auth.change_user') +class CreateStaticPageView(LoginRequiredMixin, CreateView): + template_name = "edit.html" + model = StaticPage + fields = '__all__' + success_url = reverse_lazy('settings:index') + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["title"] = "Création de page statique" + context["validate"] = "Créer" + return context + + @classmethod + def as_view(self, *args, **kwargs): + view = super().as_view(*args, **kwargs) + return staff_member_required(view) + + +class StaticPageView(DetailView): + template_name = "settings/static_page.html" + model = StaticPage + fields = '__all__' + @classmethod + def as_view(self, *args, **kwargs): + view = super().as_view(*args, **kwargs) + return staff_member_required(view) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['page'] = self.object + return context + + +class DeleteStaticPageView(DeleteView): + template_name = "confirm_delete.html" + model = StaticPage + success_url = reverse_lazy('settings:index') + @classmethod + def as_view(self, *args, **kwargs): + view = super().as_view(*args, **kwargs) + return staff_member_required(view) + + +class EditStaticPageView(UpdateView): + template_name = "edit.html" + model = StaticPage + success_url = reverse_lazy('settings:index') + fields = '__all__' + @classmethod + def as_view(self, *args, **kwargs): + view = super().as_view(*args, **kwargs) + return staff_member_required(view) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["title"] = "Édition de page statique" + context["validate"] = "Éditer" + return context + + +@staff_member_required def degrade_user(request, pk): user = get_object_or_404(User, pk=pk) - admins,_ = Group.objects.get_or_create(name='admins') - user.groups.remove(admins) + user.is_staff = False user.save() messages.success(request, user.username + ' a été enlevé des administrateurs du site') return redirect(reverse('settings:index')) -@permission_required('auth.change_user') +@staff_member_required def promote_user(request): user_form = SelectUserForm(request.POST or None) user_form.populate() if user_form.is_valid(): user=user_form.get_user() - admins,_ = Group.objects.get_or_create(name='admins') - user.groups.add(admins) + user.is_staff = True user.save() messages.success(request, user.username + ' a été ajouté des administrateurs du site') return redirect(reverse('settings:index')) diff --git a/site_tps/wsgi.py b/site_tps/wsgi.py index f3ddb29..90123c0 100644 --- a/site_tps/wsgi.py +++ b/site_tps/wsgi.py @@ -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 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 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "site_tps.settings") - application = get_wsgi_application() diff --git a/static/ValeriaBoldGrunge.ttf b/static/ValeriaBoldGrunge.ttf deleted file mode 100644 index e8c6bc7..0000000 Binary files a/static/ValeriaBoldGrunge.ttf and /dev/null differ diff --git a/static/Western Dead.ttf b/static/Western Dead.ttf new file mode 100644 index 0000000..d221b81 Binary files /dev/null and b/static/Western Dead.ttf differ diff --git a/templates/base.html b/templates/base.html index 1aef4ac..203ca01 100644 --- a/templates/base.html +++ b/templates/base.html @@ -28,11 +28,12 @@ body { @font-face { font-family: 'Valeria'; font-style: normal; - src: url("/static/ValeriaBoldGrunge.ttf"); + src: url("/static/Western Dead.ttf"); } h1.site-title { font-family: 'Valeria'; + font-size: 5rem; } {% block style %}{% endblock %} diff --git a/templates/home.html b/templates/home.html index 7dad9f1..7801037 100644 --- a/templates/home.html +++ b/templates/home.html @@ -1,6 +1,6 @@ {% extends 'base.html'%} {% block content %} -

IL ETAIT UNE FOIS DANS L'EST

+

IL ETAIT UNE FOIS DANS L'EST



diff --git a/templates/nav_bar.html b/templates/nav_bar.html index 424cd60..215eae3 100644 --- a/templates/nav_bar.html +++ b/templates/nav_bar.html @@ -2,6 +2,7 @@ {% load load_settings %} {% load_categories %} {% load_site_settings %} +{% load_static_pages %}