Des vues et des formulaires moches

This commit is contained in:
Evarin 2017-04-07 03:01:27 +02:00
parent 1cd72e4afb
commit 44ddb67332
20 changed files with 18948 additions and 17 deletions

1
.gitignore vendored
View file

@ -110,3 +110,4 @@ migrations/
.#* .#*
*.sqlite3 *.sqlite3
.sass-cache .sass-cache
/static/

View file

@ -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)

View file

@ -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):
@ -160,6 +157,9 @@ class Stage(models.Model):
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)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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

File diff suppressed because one or more lines are too long

View file

@ -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";}

View 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 %}

View 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 %}

View 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 %}

View 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 %}

View file

@ -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>

View file

@ -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'),
] ]

View file

@ -1,13 +1,77 @@
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')

View file

@ -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')

View file

@ -20,3 +20,5 @@ MIDDLEWARE_CLASSES += (
) )
SPATIALITE_LIBRARY_PATH = 'mod_spatialite' SPATIALITE_LIBRARY_PATH = 'mod_spatialite'
STATIC_ROOT = "/home/evarin/Bureau/experiENS/static/"

View file

@ -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)),
] ]

View file

@ -3,3 +3,5 @@ django-cas-ng
django-taggit django-taggit
python-ldap python-ldap
django-richtextfield django-richtextfield
django-braces
django-taggit-autosuggest