Des vues et des formulaires moches
This commit is contained in:
parent
1cd72e4afb
commit
44ddb67332
20 changed files with 18948 additions and 17 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -109,4 +109,5 @@ migrations/
|
||||||
\#*
|
\#*
|
||||||
.#*
|
.#*
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
.sass-cache
|
.sass-cache
|
||||||
|
/static/
|
|
@ -1,3 +1,34 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.contrib.auth.admin import UserAdmin
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from avisstage.models import *
|
||||||
|
|
||||||
# Register your models here.
|
class NormalienInline(admin.StackedInline):
|
||||||
|
model = Normalien
|
||||||
|
inline_classes = ("collapse open",)
|
||||||
|
|
||||||
|
class UserAdmin(UserAdmin):
|
||||||
|
inlines = (NormalienInline, )
|
||||||
|
|
||||||
|
class AvisLieuInline(admin.StackedInline):
|
||||||
|
model = AvisLieu
|
||||||
|
inline_classes = ("collapse open",)
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
class AvisStageInline(admin.StackedInline):
|
||||||
|
model = AvisStage
|
||||||
|
inline_classes = ("collapse open",)
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
class StageAdmin(admin.ModelAdmin):
|
||||||
|
inlines = (AvisLieuInline, AvisStageInline)
|
||||||
|
|
||||||
|
class StageMatiereAdmin(admin.ModelAdmin):
|
||||||
|
model = StageMatiere
|
||||||
|
prepopulated_fields = {"slug": ('nom',)}
|
||||||
|
|
||||||
|
admin.site.unregister(User)
|
||||||
|
admin.site.register(User, UserAdmin)
|
||||||
|
admin.site.register(Lieu)
|
||||||
|
admin.site.register(StageMatiere, StageMatiereAdmin)
|
||||||
|
admin.site.register(Stage, StageAdmin)
|
||||||
|
|
|
@ -7,8 +7,10 @@ from django.contrib.auth.models import User
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from django.template.defaultfilters import slugify
|
from django.template.defaultfilters import slugify
|
||||||
from django.contrib.gis.db import models as geomodels
|
from django.contrib.gis.db import models as geomodels
|
||||||
|
from django.forms.widgets import DateInput
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
from taggit.managers import TaggableManager
|
from taggit_autosuggest.managers import TaggableManager
|
||||||
|
|
||||||
from djrichtextfield.models import RichTextField
|
from djrichtextfield.models import RichTextField
|
||||||
from .utils import choices_length
|
from .utils import choices_length
|
||||||
|
@ -26,7 +28,7 @@ class Normalien(models.Model):
|
||||||
# Infos spécifiques
|
# Infos spécifiques
|
||||||
nom = models.CharField(u"Nom complet", max_length=255, blank=True)
|
nom = models.CharField(u"Nom complet", max_length=255, blank=True)
|
||||||
promotion = models.CharField(u"Promotion", max_length=40, blank=True)
|
promotion = models.CharField(u"Promotion", max_length=40, blank=True)
|
||||||
mail = models.CharField(u"Adresse e-mail permanente",
|
mail = models.EmailField(u"Adresse e-mail permanente",
|
||||||
max_length=200, blank=True)
|
max_length=200, blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -117,12 +119,7 @@ class StageMatiere(models.Model):
|
||||||
verbose_name_plural = "Matières des stages"
|
verbose_name_plural = "Matières des stages"
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.nom
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
if not self.id:
|
|
||||||
self.slug = slugify(self.nom)
|
|
||||||
super(StageMatiere, self).save(*args, **kwargs)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Un stage
|
# Un stage
|
||||||
|
@ -150,7 +147,7 @@ class Stage(models.Model):
|
||||||
|
|
||||||
# Avis
|
# Avis
|
||||||
lieux = models.ManyToManyField(Lieu, related_name="stages",
|
lieux = models.ManyToManyField(Lieu, related_name="stages",
|
||||||
through="AvisLieu")
|
through="AvisLieu", blank=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def avis_lieux(self):
|
def avis_lieux(self):
|
||||||
|
@ -159,6 +156,9 @@ class Stage(models.Model):
|
||||||
@property
|
@property
|
||||||
def lieu_principal(self):
|
def lieu_principal(self):
|
||||||
return self.avis_lieux[0].lieu
|
return self.avis_lieux[0].lieu
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse('avisstage:stage', self)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s (par %s)" % (self.sujet, self.auteur.user_id)
|
return u"%s (par %s)" % (self.sujet, self.auteur.user_id)
|
||||||
|
|
7
avisstage/static/css/jquery-ui.min.css
vendored
Normal file
7
avisstage/static/css/jquery-ui.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5
avisstage/static/js/jquery-1.12.4.min.js
vendored
Normal file
5
avisstage/static/js/jquery-1.12.4.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
avisstage/static/js/jquery-3.2.0.min.js
vendored
Normal file
4
avisstage/static/js/jquery-3.2.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
18706
avisstage/static/js/jquery-ui.js
vendored
Normal file
18706
avisstage/static/js/jquery-ui.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
13
avisstage/static/js/jquery-ui.min.js
vendored
Normal file
13
avisstage/static/js/jquery-ui.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -4,7 +4,10 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>{% block title %}ExperiENS{% endblock %}</title>
|
<title>{% block title %}ExperiENS{% endblock %}</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="{% static 'css/jquery-ui.min.css' %}" />
|
||||||
<link type="text/css" rel="stylesheet" href="{% static 'css/screen.css' %}" />
|
<link type="text/css" rel="stylesheet" href="{% static 'css/screen.css' %}" />
|
||||||
|
<script type="text/javascript" src="{% static "js/jquery-3.2.0.min.js" %}"></script>
|
||||||
|
<script type="text/javascript" src="{% static "js/jquery-ui.min.js" %}"></script>
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function showFeedback(show){document.getElementById("feedback_win").style.display=show?"table":"none";}
|
function showFeedback(show){document.getElementById("feedback_win").style.display=show?"table":"none";}
|
||||||
|
|
23
avisstage/templates/avisstage/detail/profil.html
Normal file
23
avisstage/templates/avisstage/detail/profil.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{% extends "avisstage/base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Profil de {{ object.nom }}</h1>
|
||||||
|
{% if object.user == request.user %}
|
||||||
|
<p><a href="{% url "avisstage:profil_edit" %}">Modifier mes infos</a></p>
|
||||||
|
{% endif %}
|
||||||
|
<p><b>Promotion :</b> {{ object.promotion }}</p>
|
||||||
|
<p>Adresse de contact : <a href="mailto:{{ object.mail }}">{{ object.mail }}</a></p>
|
||||||
|
<article>
|
||||||
|
<h2>Ses stages</h2>
|
||||||
|
<ul class="stagelist">
|
||||||
|
{% for stage in object.stages_publics %}
|
||||||
|
<li>
|
||||||
|
<a href="{% url "avisstage:stage" stage.id %}">
|
||||||
|
{{ stage.sujet }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</article>
|
||||||
|
{% endblock %}
|
23
avisstage/templates/avisstage/detail/stage.html
Normal file
23
avisstage/templates/avisstage/detail/stage.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{% extends "avisstage/base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Profil de {{ object.nom }}</h1>
|
||||||
|
{% if object.user == request.user %}
|
||||||
|
<p><a href="{% url "avisstage:profil_edit" %}">Modifier mes infos</a></p>
|
||||||
|
{% endif %}
|
||||||
|
<p><b>Promotion :</b> {{ object.promotion }}</p>
|
||||||
|
<p>Adresse de contact : <a href="mailto:{{ object.mail }}">{{ object.mail }}</a></p>
|
||||||
|
<article>
|
||||||
|
<h2>Ses stages</h2>
|
||||||
|
<ul class="stagelist">
|
||||||
|
{% for stage in object.stages_publics %}
|
||||||
|
<li>
|
||||||
|
<a href="{% url "avisstage:stage" stage.id %}">
|
||||||
|
{{ stage.sujet }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</article>
|
||||||
|
{% endblock %}
|
11
avisstage/templates/avisstage/formulaires/profil.html
Normal file
11
avisstage/templates/avisstage/formulaires/profil.html
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{% extends "avisstage/base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Editer mon profil</h1>
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.as_p }}
|
||||||
|
<input type="submit" />
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
24
avisstage/templates/avisstage/formulaires/stage.html
Normal file
24
avisstage/templates/avisstage/formulaires/stage.html
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{% extends "avisstage/base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
|
||||||
|
{% block extra_head %}
|
||||||
|
<link href="{% static "jquery-autosuggest/css/autoSuggest-upshot.css" %}"
|
||||||
|
type="text/css" media="all" rel="stylesheet" />
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="{% static "jquery-autosuggest/js/jquery.autoSuggest.minified.js" %}"> </script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$( function() {
|
||||||
|
$( ".datepicker" ).datepicker({ dateFormat: 'dd/mm/yy' });
|
||||||
|
} );
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Ajouter un stage</h1>
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.as_p }}
|
||||||
|
<input type="submit" />
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -3,12 +3,12 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Mon espace personnel</h1>
|
<h1>Mon espace personnel</h1>
|
||||||
<p>{{ user.nom }} <a href="{% monstage:profil_edit %}">Modifier mes infos</a></p>
|
<p><a href="{% url "avisstage:profil" user %}">{{ user.profil.nom }}</a> <a href="{% url "avisstage:profil_edit" %}">Modifier mes infos</a></p>
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
<h2>Mes stages</h2>
|
<h2>Mes stages</h2>
|
||||||
<ul class="stagelist">
|
<ul class="stagelist">
|
||||||
{% for stage in user.profil.stages %}
|
{% for stage in user.profil.stages.all %}
|
||||||
<li class="stage-{{ stage.published|yesno:"publie,brouillon" }}">
|
<li class="stage-{{ stage.published|yesno:"publie,brouillon" }}">
|
||||||
<a href="{% url "avisstage:stage" stage.id %}">
|
<a href="{% url "avisstage:stage" stage.id %}">
|
||||||
{{ stage.sujet }}
|
{{ stage.sujet }}
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<li class="stage-ajout">
|
<li class="stage-ajout">
|
||||||
<a href="{% url "avisstage:stage_ajout" stage.id %}">
|
<a href="{% url "avisstage:stage_ajout" %}">
|
||||||
Ajouter un stage
|
Ajouter un stage
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -4,7 +4,12 @@ from . import views
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.index, name='index'),
|
url(r'^$', views.index, name='index'),
|
||||||
url(r'^perso/$', views.perso, name='perso'),
|
url(r'^perso/$', views.perso, name='perso'),
|
||||||
url(r'^profil/show/(?P<profil_id>\w+)/$', views.profil, name='profil'),
|
url(r'^stage/nouveau/$', views.StageAjout.as_view(), name='stage_ajout'),
|
||||||
|
url(r'^stage/(?P<pk>\w+)/$', views.StageView.as_view(), name='stage'),
|
||||||
|
|
||||||
|
url(r'^profil/show/(?P<username>\w+)/$', views.ProfilView.as_view(),
|
||||||
|
name='profil'),
|
||||||
|
url(r'^profil/edit/$', views.ProfilEdit.as_view(), name='profil_edit'),
|
||||||
url(r'^recherche/$', views.recherche, name='recherche'),
|
url(r'^recherche/$', views.recherche, name='recherche'),
|
||||||
url(r'^feedback/$', views.feedback, name='feedback'),
|
url(r'^feedback/$', views.feedback, name='feedback'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,14 +1,78 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
from django.views.generic import DetailView
|
||||||
|
from django.views.generic.edit import UpdateView, CreateView
|
||||||
|
from django import forms
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from braces.views import LoginRequiredMixin
|
||||||
|
|
||||||
|
from avisstage.models import Normalien, Stage
|
||||||
|
|
||||||
|
# Page d'accueil
|
||||||
def index(request):
|
def index(request):
|
||||||
return render(request, 'avisstage/index.html')
|
return render(request, 'avisstage/index.html')
|
||||||
|
|
||||||
|
# Espace personnel
|
||||||
|
@login_required
|
||||||
def perso(request):
|
def perso(request):
|
||||||
return render(request, 'avisstage/perso.html')
|
return render(request, 'avisstage/perso.html')
|
||||||
|
|
||||||
def profil(request, profil_id):
|
# Profil
|
||||||
return render(request, 'avisstage/profil.html')
|
class ProfilEdit(UpdateView, LoginRequiredMixin):
|
||||||
|
model = Normalien
|
||||||
|
fields = ['nom', 'promotion', 'mail']
|
||||||
|
template_name = 'avisstage/formulaires/profil.html'
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
return self.request.user.profil
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
print kwargs
|
||||||
|
return super(ProfilEdit, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse('avisstage:perso')
|
||||||
|
|
||||||
|
class ProfilView(DetailView, LoginRequiredMixin):
|
||||||
|
model = Normalien
|
||||||
|
template_name = 'avisstage/detail/profil.html'
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
return Normalien.objects.get(user__username=self.kwargs.get('username'))
|
||||||
|
|
||||||
|
# Stages
|
||||||
|
class StageForm(forms.ModelForm):
|
||||||
|
date_widget = forms.DateInput(attrs={"class":"datepicker"})
|
||||||
|
date_debut = forms.DateField(input_formats=["%d/%m/%Y"], widget=date_widget)
|
||||||
|
date_fin = forms.DateField(input_formats=["%d/%m/%Y"], widget=date_widget)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Stage
|
||||||
|
fields = ['sujet', 'date_debut', 'date_fin', 'type_stage', 'thematiques', 'matieres', 'encadrants']
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.request = kwargs.pop("request")
|
||||||
|
super(StageForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def save(self, commit=True):
|
||||||
|
self.instance.auteur = self.request.user.profil
|
||||||
|
super(StageForm, self).save(commit=commit)
|
||||||
|
|
||||||
|
class StageAjout(CreateView, LoginRequiredMixin):
|
||||||
|
model = Stage
|
||||||
|
form_class = StageForm
|
||||||
|
template_name = 'avisstage/formulaires/stage.html'
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super(StageAjout, self).get_form_kwargs()
|
||||||
|
kwargs.update({'request': self.request})
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
class StageView(DetailView, LoginRequiredMixin):
|
||||||
|
model = Stage
|
||||||
|
template_name = 'avisstage/detail/stage.html'
|
||||||
|
|
||||||
def recherche(request):
|
def recherche(request):
|
||||||
return render(request, 'avisstage/recherche.html')
|
return render(request, 'avisstage/recherche.html')
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ https://docs.djangoproject.com/en/1.7/ref/settings/
|
||||||
|
|
||||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
import os
|
import os
|
||||||
|
from django.core.urlresolvers import reverse_lazy
|
||||||
|
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
# Quick-start development settings - unsuitable for production
|
||||||
|
@ -29,8 +31,10 @@ INSTALLED_APPS = (
|
||||||
'django.contrib.gis',
|
'django.contrib.gis',
|
||||||
|
|
||||||
'django_cas_ng',
|
'django_cas_ng',
|
||||||
|
'braces',
|
||||||
'djrichtextfield',
|
'djrichtextfield',
|
||||||
'taggit',
|
'taggit',
|
||||||
|
'taggit_autosuggest',
|
||||||
'avisstage'
|
'avisstage'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -109,3 +113,5 @@ AUTHENTICATION_BACKENDS = (
|
||||||
)
|
)
|
||||||
|
|
||||||
CAS_SERVER_URL = "https://cas.eleves.ens.fr/"
|
CAS_SERVER_URL = "https://cas.eleves.ens.fr/"
|
||||||
|
|
||||||
|
LOGIN_URL = reverse_lazy('login')
|
||||||
|
|
|
@ -20,3 +20,5 @@ MIDDLEWARE_CLASSES += (
|
||||||
)
|
)
|
||||||
|
|
||||||
SPATIALITE_LIBRARY_PATH = 'mod_spatialite'
|
SPATIALITE_LIBRARY_PATH = 'mod_spatialite'
|
||||||
|
|
||||||
|
STATIC_ROOT = "/home/evarin/Bureau/experiENS/static/"
|
||||||
|
|
|
@ -9,5 +9,6 @@ urlpatterns = [
|
||||||
url(r'^login/$', django_cas_views.login, name = "login"),
|
url(r'^login/$', django_cas_views.login, name = "login"),
|
||||||
url(r'^logout/$', django_cas_views.logout, name = "logout"),
|
url(r'^logout/$', django_cas_views.logout, name = "logout"),
|
||||||
url(r'^djrichtextfield/', include('djrichtextfield.urls')),
|
url(r'^djrichtextfield/', include('djrichtextfield.urls')),
|
||||||
|
url(r'^taggit_autosuggest/', include('taggit_autosuggest.urls')),
|
||||||
url(r'^admin/', include(admin.site.urls)),
|
url(r'^admin/', include(admin.site.urls)),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,3 +3,5 @@ django-cas-ng
|
||||||
django-taggit
|
django-taggit
|
||||||
python-ldap
|
python-ldap
|
||||||
django-richtextfield
|
django-richtextfield
|
||||||
|
django-braces
|
||||||
|
django-taggit-autosuggest
|
||||||
|
|
Loading…
Reference in a new issue