Des vues et des formulaires moches
This commit is contained in:
parent
1cd72e4afb
commit
44ddb67332
20 changed files with 18948 additions and 17 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -110,3 +110,4 @@ migrations/
|
|||
.#*
|
||||
*.sqlite3
|
||||
.sass-cache
|
||||
/static/
|
|
@ -1,3 +1,34 @@
|
|||
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.template.defaultfilters import slugify
|
||||
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 .utils import choices_length
|
||||
|
@ -26,7 +28,7 @@ class Normalien(models.Model):
|
|||
# Infos spécifiques
|
||||
nom = models.CharField(u"Nom complet", max_length=255, 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)
|
||||
|
||||
class Meta:
|
||||
|
@ -117,12 +119,7 @@ class StageMatiere(models.Model):
|
|||
verbose_name_plural = "Matières des stages"
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.id:
|
||||
self.slug = slugify(self.nom)
|
||||
super(StageMatiere, self).save(*args, **kwargs)
|
||||
return self.nom
|
||||
|
||||
#
|
||||
# Un stage
|
||||
|
@ -150,7 +147,7 @@ class Stage(models.Model):
|
|||
|
||||
# Avis
|
||||
lieux = models.ManyToManyField(Lieu, related_name="stages",
|
||||
through="AvisLieu")
|
||||
through="AvisLieu", blank=True)
|
||||
|
||||
@property
|
||||
def avis_lieux(self):
|
||||
|
@ -160,6 +157,9 @@ class Stage(models.Model):
|
|||
def lieu_principal(self):
|
||||
return self.avis_lieux[0].lieu
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('avisstage:stage', self)
|
||||
|
||||
def __unicode__(self):
|
||||
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>
|
||||
<meta charset="utf-8" />
|
||||
<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' %}" />
|
||||
<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 %}
|
||||
<script type="text/javascript">
|
||||
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 %}
|
||||
<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>
|
||||
<h2>Mes stages</h2>
|
||||
<ul class="stagelist">
|
||||
{% for stage in user.profil.stages %}
|
||||
{% for stage in user.profil.stages.all %}
|
||||
<li class="stage-{{ stage.published|yesno:"publie,brouillon" }}">
|
||||
<a href="{% url "avisstage:stage" stage.id %}">
|
||||
{{ stage.sujet }}
|
||||
|
@ -16,7 +16,7 @@
|
|||
</li>
|
||||
{% endfor %}
|
||||
<li class="stage-ajout">
|
||||
<a href="{% url "avisstage:stage_ajout" stage.id %}">
|
||||
<a href="{% url "avisstage:stage_ajout" %}">
|
||||
Ajouter un stage
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -4,7 +4,12 @@ from . import views
|
|||
urlpatterns = [
|
||||
url(r'^$', views.index, name='index'),
|
||||
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'^feedback/$', views.feedback, name='feedback'),
|
||||
]
|
||||
|
|
|
@ -1,13 +1,77 @@
|
|||
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):
|
||||
return render(request, 'avisstage/index.html')
|
||||
|
||||
# Espace personnel
|
||||
@login_required
|
||||
def perso(request):
|
||||
return render(request, 'avisstage/perso.html')
|
||||
|
||||
def profil(request, profil_id):
|
||||
return render(request, 'avisstage/profil.html')
|
||||
# Profil
|
||||
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):
|
||||
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, ...)
|
||||
import os
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
|
@ -29,8 +31,10 @@ INSTALLED_APPS = (
|
|||
'django.contrib.gis',
|
||||
|
||||
'django_cas_ng',
|
||||
'braces',
|
||||
'djrichtextfield',
|
||||
'taggit',
|
||||
'taggit_autosuggest',
|
||||
'avisstage'
|
||||
)
|
||||
|
||||
|
@ -109,3 +113,5 @@ AUTHENTICATION_BACKENDS = (
|
|||
)
|
||||
|
||||
CAS_SERVER_URL = "https://cas.eleves.ens.fr/"
|
||||
|
||||
LOGIN_URL = reverse_lazy('login')
|
||||
|
|
|
@ -20,3 +20,5 @@ MIDDLEWARE_CLASSES += (
|
|||
)
|
||||
|
||||
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'^logout/$', django_cas_views.logout, name = "logout"),
|
||||
url(r'^djrichtextfield/', include('djrichtextfield.urls')),
|
||||
url(r'^taggit_autosuggest/', include('taggit_autosuggest.urls')),
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
]
|
||||
|
|
|
@ -3,3 +3,5 @@ django-cas-ng
|
|||
django-taggit
|
||||
python-ldap
|
||||
django-richtextfield
|
||||
django-braces
|
||||
django-taggit-autosuggest
|
||||
|
|
Loading…
Reference in a new issue