Browse Source

Style d'affichage sur les catégories

master
Klafyvel 8 years ago
parent
commit
47d96bbef9
  1. 6
      content/migrations/0001_initial.py
  2. 23
      content/migrations/0002_auto_20180124_1043.py
  3. 9
      content/models.py
  4. 51
      content/templates/content/content_list.html
  5. 12
      content/views.py
  6. 2
      requirements.txt
  7. 14
      settings/migrations/0001_initial.py
  8. 31
      settings/migrations/0002_auto_20180114_1832.py
  9. 59
      settings/migrations/0003_auto_20180114_1837.py
  10. 2
      settings/models.py
  11. 7
      settings/views.py
  12. 5
      site_tps/settings.py
  13. 5
      site_tps/urls.py
  14. 3
      templates/base.html
  15. 5
      templates/edit.html
  16. 3
      templates/nav_bar.html
  17. 7
      users/migrations/0001_initial.py
  18. 23
      users/migrations/0002_auto_20180131_1052.py
  19. 6
      users/urls.py
  20. 7
      users/views.py
  21. 0
      vote/__init__.py
  22. 5
      vote/admin.py
  23. 5
      vote/apps.py
  24. 39
      vote/migrations/0001_initial.py
  25. 0
      vote/migrations/__init__.py
  26. 22
      vote/models.py
  27. 6
      vote/templates/vote/home.html
  28. 3
      vote/tests.py
  29. 7
      vote/urls.py
  30. 7
      vote/views.py

6
content/migrations/0001_initial.py

@ -1,4 +1,4 @@
# Generated by Django 2.0.1 on 2018-01-24 10:29 # Generated by Django 2.0.1 on 2018-02-28 12:53
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
@ -17,7 +17,9 @@ class Migration(migrations.Migration):
name='Category', name='Category',
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')),
('Nom de la catégorie', models.CharField(max_length=255)), ('name', models.CharField(max_length=255, verbose_name='Nom de la catégorie')),
('description', models.TextField(default='', verbose_name='Descriton de la catégorie')),
('image', models.ImageField(null=True, upload_to='', verbose_name='Illustration de la catégorie')),
], ],
), ),
migrations.CreateModel( migrations.CreateModel(

23
content/migrations/0002_auto_20180124_1043.py

@ -1,23 +0,0 @@
# Generated by Django 2.0.1 on 2018-01-24 10:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('content', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='category',
name='Nom de la catégorie',
),
migrations.AddField(
model_name='category',
name='name',
field=models.CharField(default='Nom de la catégorie', max_length=255, verbose_name='Nom de la catégorie'),
preserve_default=False,
),
]

9
content/models.py

@ -1,6 +1,7 @@
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.conf import settings
class Category(models.Model): class Category(models.Model):
@ -9,6 +10,14 @@ class Category(models.Model):
max_length=255, max_length=255,
verbose_name="Nom de la catégorie" verbose_name="Nom de la catégorie"
) )
description = models.TextField(
verbose_name="Descriton de la catégorie",
default=""
)
image = models.ImageField(
verbose_name="Illustration de la catégorie",
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})

51
content/templates/content/content_list.html

@ -1,17 +1,42 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load staticfiles %}
{% block style %}
.page-title
{
background-image : url("{{category.image.url}}");
background-attachment : fixed;
background-position: center;
}
.title-block
{
background-color: rgba(248, 249, 250, 0.6);
}
{% endblock %}
{% block content %} {% block content %}
<script>
{% if category %} function show_content () {
<h1>{{category.name}}</h1> $('html, body').animate({scrollTop: $('#category-content').offset().top}, 800);
{% else %} }
<h1>Liste des contenus</h1> </script>
{% endif %} <div class="position-relative overflow-hidden p-3 p-md-5 m-md-3 text-center bg-light page-title">
<div class="col-md-5 p-lg-5 mx-auto my-5 title-block">
{% for content in contents %} <h1 class="display-4 font-weight-normal">{{category.name}}</h1>
<div> <p class="lead font-weight-normal">{{category.description}}</p>
<h2>{{content.name}}</h2> <a class="btn btn-outline-secondary smooth-scroll" href="#category-content">Aller voir !</a>
<h3>Contenu proposé par {{content.group_owner.name}}</h3> </div>
<a href="{{content.content_url}}">C'est ici que ça se passe</a> </div>
<br />
<span id="category-content"></span>
{% for content in contents %}
<div class="bg-dark pt-3 px-3 pt-md-5 px-md-5 text-center text-white overflow-hidden">
<div class="my-3 py-3">
<h2 class="display-5">{{content.name}}</h2>
<p class="lead">Contenu proposé par {{content.group_owner.name}}</p>
</div>
<video controls>
<source src="{{content.content_url}}" type="video/mp4">
</video>
</div>
{% endfor %}
</div> </div>
{% endfor %}
{% endblock %} {% endblock %}

12
content/views.py

@ -28,6 +28,12 @@ class CreateCategory(generic.CreateView):
"""Création de catégorie.""" """Création de catégorie."""
model = Category model = Category
fields = '__all__' fields = '__all__'
template_name = "edit.html"
def get_context_data(self, **kwargs):
context = super(generic.CreateView, self).get_context_data(**kwargs)
context['title'] = "Création de catégorie"
return context
class DeleteCategory(generic.DeleteView): class DeleteCategory(generic.DeleteView):
@ -42,3 +48,9 @@ class EditCategory(generic.UpdateView):
model = Category model = Category
fields = '__all__' fields = '__all__'
template_name = "edit.html" template_name = "edit.html"
def get_context_data(self, **kwargs):
context = super(generic.UpdateView, self).get_context_data(**kwargs)
context['title'] = "Édition de " + self.object.name
return context

2
requirements.txt

@ -1,3 +1,5 @@
Django==2.0.1 Django==2.0.1
django-bootstrap4==0.0.6
Pillow==5.0.0
pycrypto==2.6.1 pycrypto==2.6.1
pytz==2017.3 pytz==2017.3

14
settings/migrations/0001_initial.py

@ -1,7 +1,7 @@
# Generated by Django 2.0.1 on 2018-01-14 18:04 # Generated by Django 2.0.1 on 2018-02-28 12:53
from django.db import migrations, models from django.db import migrations, models
import settings.models import settings.aes_field
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -16,17 +16,17 @@ class Migration(migrations.Migration):
name='ContentSettings', name='ContentSettings',
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')),
('URL du FTP', models.URLField(max_length=255)), ('ftp_url', models.URLField(default='', max_length=255, verbose_name='URL du FTP')),
('Identifiant sur le FTP', models.CharField(max_length=255)), ('ftp_id', models.CharField(default='', max_length=255, verbose_name='Identifiant sur le FTP')),
('Mot de passe', settings.models.AESEncryptedField(max_length=255)), ('ftp_pass', settings.aes_field.AESEncryptedField(default='', max_length=255, verbose_name='Mot de passe')),
], ],
), ),
migrations.CreateModel( migrations.CreateModel(
name='SiteSettings', name='SiteSettings',
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')),
('allow_upload', models.BooleanField(help_text="Autoriser l'upload de vidéos.")), ('allow_upload', models.BooleanField(default=False, verbose_name="Autoriser l'upload de vidéos.")),
('site_name', models.CharField(help_text='Nom du site', max_length=255)), ('home_message', models.TextField(default='', verbose_name="Message de la page d'accueil")),
], ],
), ),
] ]

31
settings/migrations/0002_auto_20180114_1832.py

@ -1,31 +0,0 @@
# Generated by Django 2.0.1 on 2018-01-14 18:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('settings', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='sitesettings',
name='allow_upload',
),
migrations.RemoveField(
model_name='sitesettings',
name='site_name',
),
migrations.AddField(
model_name='sitesettings',
name="Autoriser l'upload de vidéos.",
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='sitesettings',
name="Message de la page d'accueil",
field=models.TextField(default=''),
),
]

59
settings/migrations/0003_auto_20180114_1837.py

@ -1,59 +0,0 @@
# Generated by Django 2.0.1 on 2018-01-14 18:37
from django.db import migrations, models
import settings.models
class Migration(migrations.Migration):
dependencies = [
('settings', '0002_auto_20180114_1832'),
]
operations = [
migrations.RemoveField(
model_name='contentsettings',
name='Identifiant sur le FTP',
),
migrations.RemoveField(
model_name='contentsettings',
name='Mot de passe',
),
migrations.RemoveField(
model_name='contentsettings',
name='URL du FTP',
),
migrations.RemoveField(
model_name='sitesettings',
name="Autoriser l'upload de vidéos.",
),
migrations.RemoveField(
model_name='sitesettings',
name="Message de la page d'accueil",
),
migrations.AddField(
model_name='contentsettings',
name='ftp_id',
field=models.CharField(default='', max_length=255, verbose_name='Identifiant sur le FTP'),
),
migrations.AddField(
model_name='contentsettings',
name='ftp_pass',
field=settings.models.AESEncryptedField(default='', max_length=255, verbose_name='Mot de passe'),
),
migrations.AddField(
model_name='contentsettings',
name='ftp_url',
field=models.URLField(default='', max_length=255, verbose_name='URL du FTP'),
),
migrations.AddField(
model_name='sitesettings',
name='allow_upload',
field=models.BooleanField(default=False, verbose_name="Autoriser l'upload de vidéos."),
),
migrations.AddField(
model_name='sitesettings',
name='home_message',
field=models.TextField(default='', verbose_name="Message de la page d'accueil"),
),
]

2
settings/models.py

@ -4,6 +4,7 @@ from .aes_field import AESEncryptedField
class ContentSettings(models.Model): class ContentSettings(models.Model):
PRETTY_NAME = "Réglages des contenus"
ftp_url = models.URLField( ftp_url = models.URLField(
max_length=255, max_length=255,
verbose_name="URL du FTP", verbose_name="URL du FTP",
@ -22,6 +23,7 @@ class ContentSettings(models.Model):
class SiteSettings(models.Model): class SiteSettings(models.Model):
PRETTY_NAME = "Réglages du site"
allow_upload = models.BooleanField( allow_upload = models.BooleanField(
verbose_name="Autoriser l'upload de vidéos.", verbose_name="Autoriser l'upload de vidéos.",
default=False, default=False,

7
settings/views.py

@ -26,3 +26,10 @@ class EditSiteSettingsView(UpdateView):
def get_object(self, queryset=None): def get_object(self, queryset=None):
obj,_ = self.model.objects.get_or_create() obj,_ = self.model.objects.get_or_create()
return obj return obj
def get_context_data(self, **kwargs):
context = super(UpdateView, self).get_context_data(**kwargs)
context['title'] = "Édition des " + self.object.PRETTY_NAME
return context

5
site_tps/settings.py

@ -39,9 +39,9 @@ INSTALLED_APPS = [
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'bootstrap4',
'settings', 'settings',
'content', 'content',
'vote',
'users', 'users',
] ]
@ -124,3 +124,6 @@ USE_TZ = True
# https://docs.djangoproject.com/en/2.0/howto/static-files/ # https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = '/static/' STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static', 'media')

5
site_tps/urls.py

@ -15,6 +15,8 @@ Including another URLconf
""" """
from django.contrib import admin from django.contrib import admin
from django.urls import include, path from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static
from . import views from . import views
@ -23,6 +25,7 @@ urlpatterns = [
path('', views.home, name="home"), path('', views.home, name="home"),
path('content/', include('content.urls')), path('content/', include('content.urls')),
path('settings/', include('settings.urls')), path('settings/', include('settings.urls')),
path('vote/', include('vote.urls')),
path('users/', include('users.urls')), path('users/', include('users.urls')),
] ]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

3
templates/base.html

@ -6,6 +6,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script defer src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script> <script defer src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<style>
{% block style %}{% endblock %}
</style>
</head> </head>
<body> <body>
{% include 'nav_bar.html' %} {% include 'nav_bar.html' %}

5
templates/edit.html

@ -1,13 +1,12 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load bootstrap3 %} {% load bootstrap4 %}
{% block content %} {% block content %}
{% if title %} {% if title %}
<h1>{{title}}</h1> <h1>{{title}}</h1>
{% endif %} {% endif %}
<form action="" method="post">{% csrf_token %} <form action="" method="post" enctype="multipart/form-data">{% csrf_token %}
{% bootstrap_form form %} {% bootstrap_form form %}
<button type="submit" class="btn btn-primary"> <button type="submit" class="btn btn-primary">
{% bootstrap_icon "star" %}
{% if validate %} {% if validate %}
{{validate}} {{validate}}
{% else %} {% else %}

3
templates/nav_bar.html

@ -14,6 +14,7 @@
</a></li> </a></li>
{% endfor %} {% endfor %}
<li class="nav-item {% if vote %}active{% endif %}"><a class="nav-link" href="{% url 'vote:home' %}">Vote</a></li>
<li class="nav-item {% if settings %}active{% endif %}"><a class="nav-link" href="{% url 'settings:index' %}">Administration</a></li> <li class="nav-item {% if settings %}active{% endif %}"><a class="nav-link" href="{% url 'settings:index' %}">Administration</a></li>
</ul>
</div>
</nav> </nav>

7
users/migrations/0001_initial.py

@ -1,4 +1,4 @@
# Generated by Django 2.0.1 on 2018-01-31 09:12 # Generated by Django 2.0.1 on 2018-02-28 12:53
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -10,8 +10,8 @@ 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),
('auth', '0009_alter_user_last_name_max_length'),
] ]
operations = [ operations = [
@ -19,7 +19,6 @@ class Migration(migrations.Migration):
name='SchoolProfile', name='SchoolProfile',
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')),
('is_school', models.BooleanField()),
('group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='auth.Group')), ('group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='auth.Group')),
], ],
), ),
@ -27,7 +26,7 @@ class Migration(migrations.Migration):
name='UserProfile', name='UserProfile',
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')),
('school', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.SchoolProfile')), ('school', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.SchoolProfile')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
], ],
), ),

23
users/migrations/0002_auto_20180131_1052.py

@ -1,23 +0,0 @@
# Generated by Django 2.0.1 on 2018-01-31 10:52
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='schoolprofile',
name='is_school',
),
migrations.AlterField(
model_name='userprofile',
name='school',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.SchoolProfile'),
),
]

6
users/urls.py

@ -4,6 +4,7 @@ from .views import (
CreateUserProfile, CreateUserProfile,
CreateSchool, CreateSchool,
EditSchool, EditSchool,
DeleteSchool,
) )
app_name = 'users' app_name = 'users'
@ -28,4 +29,9 @@ urlpatterns = [
EditSchool.as_view(), EditSchool.as_view(),
name='edit-school' name='edit-school'
), ),
path(
'school/<int:pk>/delete',
DeleteSchool.as_view(),
name='delete-school'
),
] ]

7
users/views.py

@ -1,5 +1,5 @@
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from django.views.generic import CreateView, UpdateView from django.views.generic import CreateView, UpdateView, DeleteView
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
@ -79,3 +79,8 @@ class EditSchool(UpdateView):
context['title'] = "Édition de l'école" context['title'] = "Édition de l'école"
context['validate'] = "Modifier" context['validate'] = "Modifier"
return context return context
class DeleteSchool(DeleteView):
model = Group

0
vote/__init__.py

5
vote/admin.py

@ -1,5 +0,0 @@
from django.contrib import admin
from .models import Vote, Poll
admin.site.register(Vote)
admin.site.register(Poll)

5
vote/apps.py

@ -1,5 +0,0 @@
from django.apps import AppConfig
class VoteConfig(AppConfig):
name = 'vote'

39
vote/migrations/0001_initial.py

@ -1,39 +0,0 @@
# Generated by Django 2.0.1 on 2018-01-24 10:29
from django.conf import settings
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0009_alter_user_last_name_max_length'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('content', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Poll',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=1024)),
('contents', models.ManyToManyField(to='content.Content')),
('voters_group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group')),
],
),
migrations.CreateModel(
name='Vote',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('vote', models.IntegerField(validators=[django.core.validators.MaxValueValidator(5), django.core.validators.MinValueValidator(0)])),
('content', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='content.Content')),
('poll', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vote.Poll')),
('votant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

0
vote/migrations/__init__.py

22
vote/models.py

@ -1,22 +0,0 @@
from django.db import models
from django.core import validators
from content.models import Content
from django.contrib.auth.models import Group, User
class Poll(models.Model):
voters_group = models.ForeignKey(Group, on_delete=models.CASCADE)
contents = models.ManyToManyField(Content)
title = models.CharField(max_length=1024)
class Vote(models.Model):
votant = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.ForeignKey(Content, on_delete=models.CASCADE)
poll = models.ForeignKey(Poll, on_delete=models.CASCADE)
vote = models.IntegerField(
validators=[
validators.MaxValueValidator(5),
validators.MinValueValidator(0)
]
)

6
vote/templates/vote/home.html

@ -1,6 +0,0 @@
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h2>Votes disponibles</h2>
</div>
{% endblock %}

3
vote/tests.py

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

7
vote/urls.py

@ -1,7 +0,0 @@
from django.urls import path
from . import views
app_name = 'vote'
urlpatterns = [
path('home', views.home, name='home')
]

7
vote/views.py

@ -1,7 +0,0 @@
from django.shortcuts import render
# Create your views here.
def home(request):
return render(request, 'vote/home.html')
Loading…
Cancel
Save