Merge branch 'ju' into 'master'
Recherche basique, visualisation d'une fiche et édition se sa fiche Closes #3 and #2 See merge request klub-dev-ens/annuaire!2
This commit is contained in:
commit
c6f134c31d
19 changed files with 758 additions and 20 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -4,11 +4,7 @@
|
|||
*~
|
||||
*#
|
||||
|
||||
/media/archives/*
|
||||
/media/images/*
|
||||
/media/documents/*
|
||||
/media/original_images/*
|
||||
/media/admin
|
||||
/media/picture
|
||||
|
||||
/recensements/
|
||||
/venv/
|
||||
|
|
|
@ -86,7 +86,8 @@ DATABASES = {
|
|||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
'NAME':
|
||||
'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
|
@ -103,7 +104,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/dev/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
LANGUAGE_CODE = 'fr-fr'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
|
@ -118,3 +119,7 @@ USE_TZ = True
|
|||
# https://docs.djangoproject.com/en/dev/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||
|
||||
MEDIA_URL = '/media/'
|
||||
|
|
|
@ -13,9 +13,17 @@ Including another URLconf
|
|||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.conf import settings
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
from django.urls import path, include
|
||||
from django.conf.urls.static import static
|
||||
from fiches.views import home
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('fiche/', include('fiches.urls')),
|
||||
path('', home, name='home')
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
|
|
@ -3,9 +3,13 @@ from fiches.models import Profile
|
|||
from fiches.models import Department
|
||||
from fiches.models import Phone
|
||||
from fiches.models import Social
|
||||
from fiches.models import Mail
|
||||
from fiches.models import Address
|
||||
|
||||
|
||||
# Register your models here.
|
||||
admin.site.register(Profile)
|
||||
admin.site.register(Department)
|
||||
admin.site.register(Phone)
|
||||
admin.site.register(Social)
|
||||
admin.site.register(Social)
|
||||
admin.site.register(Mail)
|
||||
admin.site.register(Address)
|
||||
|
|
30
fiches/forms.py
Normal file
30
fiches/forms.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
from django import forms
|
||||
from fiches.models import Profile, Department
|
||||
|
||||
|
||||
class ProfileForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Profile
|
||||
fields = [
|
||||
"full_name",
|
||||
"nickname",
|
||||
"picture",
|
||||
"department",
|
||||
"promotion",
|
||||
"birth_date",
|
||||
"thurne",
|
||||
"text_field",
|
||||
"printing",
|
||||
"keep_me"
|
||||
]
|
||||
|
||||
|
||||
class SearchForm(forms.Form):
|
||||
name = forms.CharField(label='Nom/Surnom', max_length=1023, required=False)
|
||||
year = forms.IntegerField(label='Promotion', required=False)
|
||||
department = forms.ModelMultipleChoiceField(queryset=Department.objects.all(), required=False)
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
if (not cleaned_data['name'] and not cleaned_data['year'] and not cleaned_data['department']):
|
||||
raise forms.ValidationError(('Tous les champs sont vides'), code='invalid')
|
24
fiches/migrations/0002_auto_20190408_1929.py
Normal file
24
fiches/migrations/0002_auto_20190408_1929.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Generated by Django 2.2 on 2019-04-08 19:29
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fiches', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='phone',
|
||||
name='profile',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='fiches.Profile', verbose_name='profil'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='social',
|
||||
name='profile',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='fiches.Profile', verbose_name='profil'),
|
||||
),
|
||||
]
|
47
fiches/migrations/0003_auto_20200108_2306.py
Normal file
47
fiches/migrations/0003_auto_20200108_2306.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
# Generated by Django 2.2.9 on 2020-01-08 23:06
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fiches', '0002_auto_20190408_1929'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='department',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, verbose_name='nom du département'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='phone',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, verbose_name='type'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='social',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, verbose_name='type'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Mail',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255, verbose_name='type')),
|
||||
('mail', models.CharField(max_length=1023, verbose_name='adresse mail')),
|
||||
('profile', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='fiches.Profile', verbose_name='profil')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Address',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255, verbose_name='type')),
|
||||
('content', models.CharField(max_length=1023, verbose_name='adresse')),
|
||||
('profile', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='fiches.Profile', verbose_name='profil')),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -6,7 +6,10 @@ from django.contrib.auth.models import User
|
|||
|
||||
class Profile(models.Model):
|
||||
user = models.OneToOneField(
|
||||
User, on_delete=models.CASCADE, verbose_name=_("utilisateur")
|
||||
User,
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_("utilisateur"),
|
||||
related_name="profile",
|
||||
)
|
||||
full_name = models.CharField(max_length=1023, verbose_name=_("nom"))
|
||||
nickname = models.CharField(blank=True, max_length=1023, verbose_name=_("surnom"))
|
||||
|
@ -27,22 +30,56 @@ class Profile(models.Model):
|
|||
default=False, verbose_name=_("conserver la fiche annuaire ?")
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.full_name
|
||||
|
||||
|
||||
class Department(models.Model):
|
||||
name = models.CharField(max_length=1023, verbose_name=_("nom du département"))
|
||||
name = models.CharField(max_length=255, verbose_name=_("nom du département"))
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class Phone(models.Model):
|
||||
profile = models.OneToOneField(
|
||||
profile = models.ForeignKey(
|
||||
Profile, on_delete=models.CASCADE, verbose_name=_("profil")
|
||||
)
|
||||
name = models.CharField(max_length=1023, verbose_name=_("type"))
|
||||
name = models.CharField(max_length=255, verbose_name=_("type"))
|
||||
number = models.CharField(max_length=1023, verbose_name=_("numéro"))
|
||||
|
||||
def __str__(self):
|
||||
return "{} : {}".format(self.name, self.number)
|
||||
|
||||
|
||||
class Social(models.Model):
|
||||
profile = models.OneToOneField(
|
||||
profile = models.ForeignKey(
|
||||
Profile, on_delete=models.CASCADE, verbose_name=_("profil")
|
||||
)
|
||||
name = models.CharField(max_length=1023, verbose_name=_("type"))
|
||||
name = models.CharField(max_length=255, verbose_name=_("type"))
|
||||
content = models.CharField(max_length=1023, verbose_name=_("contenu"))
|
||||
|
||||
def __str__(self):
|
||||
return "{} : {}".format(self.name, self.content)
|
||||
|
||||
|
||||
class Mail(models.Model):
|
||||
profile = models.ForeignKey(
|
||||
Profile, on_delete=models.CASCADE, verbose_name=_("profil")
|
||||
)
|
||||
name = models.CharField(max_length=255, verbose_name=_("type"))
|
||||
mail = models.CharField(max_length=1023, verbose_name=_("adresse mail"))
|
||||
|
||||
def __str__(self):
|
||||
return "{} : {}".format(self.name, self.mail)
|
||||
|
||||
|
||||
class Address(models.Model):
|
||||
profile = models.ForeignKey(
|
||||
Profile, on_delete=models.CASCADE, verbose_name=_("profil")
|
||||
)
|
||||
name = models.CharField(max_length=255, verbose_name=_("type"))
|
||||
content = models.CharField(max_length=1023, verbose_name=_("adresse"))
|
||||
|
||||
def __str__(self):
|
||||
return "{} : {}".format(self.name, self.content)
|
||||
|
|
351
fiches/static/fiches/css/style.css
Normal file
351
fiches/static/fiches/css/style.css
Normal file
|
@ -0,0 +1,351 @@
|
|||
html {
|
||||
background-color: black;
|
||||
color: #FFF;
|
||||
font-family: Verdana, Verdana, Geneva, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0 0 0.8em 0;
|
||||
min-height: 538px;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
a:link {
|
||||
background-color: inherit;
|
||||
color: #7978DA;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
background-color: inherit;
|
||||
color: #9CA6FF;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background-color: inherit;
|
||||
color: #006CE3;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0.6em;
|
||||
margin-bottom: 0.6em;
|
||||
}
|
||||
|
||||
.ens {
|
||||
color: #89C4FF;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.tiny {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.verytiny {
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.dark {
|
||||
color: #666;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
width: 100%;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.error {
|
||||
font-weight: bold;
|
||||
color: #FB0000;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.warning {
|
||||
font-weight: bold;
|
||||
color: #FF8A00;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.mainspacer {
|
||||
width: 100%;
|
||||
height: 0.8em;
|
||||
}
|
||||
|
||||
.success {
|
||||
font-weight: bold;
|
||||
color: #00E000;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.success a:link {
|
||||
background-color: inherit;
|
||||
color: #008800;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.success a:visited {
|
||||
background-color: inherit;
|
||||
color: #008800;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.success a:hover {
|
||||
background-color: inherit;
|
||||
color: #4FFF4F;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.block {
|
||||
background-color: #333;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
text-align: justify;
|
||||
padding: 0.5em 0.5em;
|
||||
margin: 0 1em 1em 1em;
|
||||
}
|
||||
|
||||
#main {
|
||||
padding-top: 0.5em;
|
||||
margin-left: 1em;
|
||||
background-color: transparent;
|
||||
color: #FFF;
|
||||
width: 40em;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#header {
|
||||
margin: 0 1em 0 1em;
|
||||
float: left;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
margin-top: 0;
|
||||
font-family: Georgia, sans-serif;
|
||||
}
|
||||
|
||||
#header h1 a:link, #header h1 a:visited {
|
||||
color: #FFF;
|
||||
background-color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#header h1 a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#language_switch {
|
||||
margin-top: 0.5em;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#language_switch form {
|
||||
float: left;
|
||||
padding: 0;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
#content {
|
||||
}
|
||||
|
||||
#content h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
#content h4 {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
#footer {
|
||||
padding: 0.2em 0;
|
||||
margin: 1em 5em 0 5em;
|
||||
clear: both;
|
||||
background-color: #333;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#contact {
|
||||
margin: 0.5em 8em 0 8em;
|
||||
}
|
||||
|
||||
#search {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.errorlist {
|
||||
display: inline;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.errorlist li {
|
||||
display: inline;
|
||||
font-weight: bold;
|
||||
color: #E00000;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
#advanced_search {
|
||||
border: 1px solid #CCC;
|
||||
padding: 0.5em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.advanced_filter {
|
||||
width: 50%;
|
||||
margin-top: 1px;
|
||||
margin-bottom: 1px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.advanced_filter input {
|
||||
max-width: 60%;
|
||||
}
|
||||
|
||||
.submit_button {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.add_delete_button {
|
||||
text-align: right;
|
||||
margin: 0.3em;
|
||||
}
|
||||
|
||||
#pdflink {
|
||||
text-align: right;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
#picture {
|
||||
width: 8em;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#picture img {
|
||||
margin-top: 0.3em;
|
||||
max-width: 8em;
|
||||
}
|
||||
|
||||
#infos {
|
||||
padding-left: 1em;
|
||||
float: left;
|
||||
width: 31em;
|
||||
}
|
||||
|
||||
#ficheedit {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.editfield {
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
|
||||
.editfield input {
|
||||
}
|
||||
|
||||
.editfield textarea {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top:0.2em;
|
||||
display: block;
|
||||
width: 98%;
|
||||
height: 3em;
|
||||
}
|
||||
|
||||
.message {
|
||||
margin-top: 0.3em;
|
||||
margin-bottom: 0.3em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.long_message {
|
||||
margin-top: 0.6em;
|
||||
margin-bottom: 0.6em;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
fieldset.address .editfield textarea, fieldset.quote .editfield textarea {
|
||||
height: 3em;
|
||||
}
|
||||
|
||||
fieldset.address, fieldset.quote {
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
|
||||
#main-login-container {
|
||||
width: 500px;
|
||||
margin: 3.5em auto;
|
||||
}
|
||||
|
||||
#main-login-container h3.error {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.3em;
|
||||
font-family: 'Droid Serif', serif;
|
||||
}
|
||||
|
||||
#main-login {
|
||||
width: 500px;
|
||||
border: 15px solid #333;
|
||||
-webkit-border-radius: 20px;
|
||||
-moz-border-radius: 20px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
#main-login.login_block {
|
||||
padding: 2em;
|
||||
box-shadow: 0 0 100px #AAA inset;
|
||||
}
|
||||
|
||||
a#login_clipper, a#login_outsider {
|
||||
float: left;
|
||||
display: block;
|
||||
width: 250px;
|
||||
height: 200px;
|
||||
text-align: center;
|
||||
font-family: 'Droid Serif', serif;
|
||||
font-size: 1.3em;
|
||||
font-weight: bold;
|
||||
line-height: 190px;
|
||||
text-decoration: none;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
a#login_clipper {
|
||||
background-color: #123E96;
|
||||
box-shadow: 0 0 100px #040C78 inset;
|
||||
}
|
||||
|
||||
a#login_clipper:hover {
|
||||
background-color: #164BB6;
|
||||
}
|
||||
|
||||
a#login_outsider {
|
||||
background-color: #961221;
|
||||
box-shadow: 0 0 100px #780411 inset;
|
||||
}
|
||||
|
||||
a#login_outsider:hover {
|
||||
background-color: #B31729;
|
||||
}
|
66
fiches/templates/fiches/base.html
Normal file
66
fiches/templates/fiches/base.html
Normal file
|
@ -0,0 +1,66 @@
|
|||
{% load i18n %}
|
||||
{% load staticfiles %}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>
|
||||
{% block title_onglet %}{% trans "Annuaire des élèves de l'ENS" %}{% endblock %}
|
||||
</title>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "fiches/css/style.css" %}" />
|
||||
|
||||
{% block extrahead %}{% endblock %}
|
||||
{# Pour pouvoir ajouter des trucs dans le head sur une autre page #}
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
<div id="language_switch">
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<h1>
|
||||
{% block title %} <a href='{% url "home" %}'>{% trans "Annuaire des élèves de l'ENS" %}</a>{% endblock %}
|
||||
</h1>
|
||||
{% if user.is_authenticated %}
|
||||
{% blocktrans %}Connecté en tant que <tt>{{ user }}</tt>{% endblocktrans %}<br />
|
||||
|
||||
{% endif %}
|
||||
<nav>
|
||||
<a href='{% url "home" %}'> Accueil </a>
|
||||
<a href='{% url "fiche_modif" %}'> Modifier sa fiche d'annuaire </a>
|
||||
<a href='{% url "fiche" request.user.profile.id %}'> Consulter sa fiche d'annuaire </a>
|
||||
<a href=''> Anniversaires à venir </a>
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="content">
|
||||
|
||||
{% block contentspacer %}{% endblock %}
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
</div>
|
||||
<div id="footer">
|
||||
|
||||
{% block footer %}
|
||||
[<a href="http://www.ens.fr">ENS</a>]
|
||||
[<a href="http://www.eleves.ens.fr/">{% trans "Page des élèves" %}</a>]
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
<div id="contact" class="verytiny">
|
||||
|
||||
{% block contact %}
|
||||
<a href="mailto:klub-dev@ens.fr">
|
||||
{% trans "Contacter l'équipe annuaire" %}
|
||||
</a>
|
||||
<span class="right dark" title="annuaireweb v{{ VERSION }}">
|
||||
powered by Django, KDENS
|
||||
</span>
|
||||
<div class="spacer"></div>
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
</body>
|
||||
</html>
|
66
fiches/templates/fiches/fiche.html
Normal file
66
fiches/templates/fiches/fiche.html
Normal file
|
@ -0,0 +1,66 @@
|
|||
{% extends "fiches/base.html" %}
|
||||
{% block content %}
|
||||
<div>
|
||||
<div style="width:200px;height:200px;overflow:hidden;" >
|
||||
<img src="{{ profile.picture.url }}" width="200px" height="auto"/>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ profile.full_name }}
|
||||
({{ profile.promotion }})
|
||||
{% if profile.nickname %}
|
||||
<em>alias:</em>{{ profile.nickname }})</h3>
|
||||
{% endif %}
|
||||
<p>
|
||||
{% if profile.department.exists %}
|
||||
<em>Département{{ profile.department.count|pluralize}} :</em>
|
||||
{% endif %}
|
||||
{% for dep in profile.department.all %}
|
||||
{{ dep }}
|
||||
{% if not forloop.last %}
|
||||
,
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if profile.birth_date %}
|
||||
</p>
|
||||
<p>
|
||||
{% if profile.phone_set.exists %}
|
||||
<em>Téléphone{{ profile.phone_set.count|pluralize}} :</em>
|
||||
{% endif %}
|
||||
{% for ph in profile.phone_set.all %}
|
||||
{{ ph }}
|
||||
{% if not forloop.last %}
|
||||
,<br/>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
<p>
|
||||
{% if profile.social_set.exists %}
|
||||
<em>{{ profile.social_set.count|pluralize:"Réseau social,Réseaux sociaux"}} :</em>
|
||||
{% endif %}
|
||||
{% for ph in profile.social_set.all %}
|
||||
{{ ph }}
|
||||
{% if not forloop.last %}
|
||||
,<br/>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
<p>
|
||||
<em>Date de naissance :</em> {{ profile.birth_date }}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
{% if profile.thurne %}
|
||||
<p>
|
||||
<em>Thurne :</em> {{ profile.thurne }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{% if profile.text_field %}
|
||||
<p>
|
||||
<b>Champ libre :</b> {{ profile.text_field }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
11
fiches/templates/fiches/fiches_modif.html
Normal file
11
fiches/templates/fiches/fiches_modif.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
{% extends "fiches/base.html" %}
|
||||
{% block content %}
|
||||
<h2>Modifier ma page d'annuaire</h2>
|
||||
<form method="post" action="">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Enregistrer">
|
||||
</form>
|
||||
|
||||
|
||||
{% endblock %}
|
22
fiches/templates/fiches/home.html
Normal file
22
fiches/templates/fiches/home.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
{% extends "fiches/base.html" %}
|
||||
{% block content %}
|
||||
|
||||
<h2> Chercher quelqu'un.e dans l'annuaire </h2>
|
||||
<form method='post' action="">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Recherche">
|
||||
</form>
|
||||
|
||||
|
||||
<div>
|
||||
<ul>
|
||||
{% for profile in result %}
|
||||
<li><a href="{% url 'fiche' profile.id %}">{{profile.full_name}} {{profile.departement}}
|
||||
</a> </li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
21
fiches/templates/fiches/search.html
Normal file
21
fiches/templates/fiches/search.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
{% extends "fiches/base.html" %}
|
||||
{% block content %}
|
||||
|
||||
<h2> Chercher quelqu'un.e dans l'annuaire </h2>
|
||||
<form method='post' action="">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Recherche">
|
||||
</form>
|
||||
|
||||
<div>
|
||||
<ul>
|
||||
{% for profile in result %}
|
||||
<li><a href="{% url 'fiche' profile.id %}">{{profile.full_name}} {{profile.departement}}
|
||||
</a> </li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
|
@ -1,3 +0,0 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
7
fiches/urls.py
Normal file
7
fiches/urls.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('<int:id>',views.fiche, name='fiche'),
|
||||
path('edit',views.fiche_modif, name='fiche_modif')
|
||||
]
|
|
@ -1,3 +1,41 @@
|
|||
from django.shortcuts import render
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from fiches.models import Profile
|
||||
from fiches.forms import ProfileForm, SearchForm
|
||||
from django.urls import reverse
|
||||
from django.db.models import Q
|
||||
|
||||
# Create your views here.
|
||||
|
||||
@login_required
|
||||
def fiche(request, id):
|
||||
profile = get_object_or_404(Profile, id=id)
|
||||
return render(request, 'fiches/fiche.html', {"profile": profile})
|
||||
|
||||
|
||||
@login_required
|
||||
def fiche_modif(request):
|
||||
profile = request.user.profile
|
||||
if request.method == 'POST':
|
||||
form = ProfileForm(request.POST, instance=profile)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return redirect(reverse('fiche', args=(profile.id,)))
|
||||
else:
|
||||
form = ProfileForm(instance=profile)
|
||||
|
||||
return render(request, 'fiches/fiches_modif.html', {"form": form})
|
||||
|
||||
|
||||
|
||||
@login_required
|
||||
def home(request):
|
||||
if request.method == 'POST':
|
||||
form = SearchForm(request.POST)
|
||||
if form.is_valid():
|
||||
result = Profile.objects.filter(Q(full_name__icontains=form.cleaned_data['name']) | Q(nickname__icontains=form.cleaned_data['name']))
|
||||
return render(request,'fiches/home.html',{"form":form, "result":result})
|
||||
|
||||
else:
|
||||
form = SearchForm()
|
||||
return render(request,'fiches/home.html',{"form":form})
|
||||
|
|
6
requirements-dev.txt
Normal file
6
requirements-dev.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
-r requirements.txt
|
||||
django-debug-toolbar
|
||||
ipython
|
||||
black
|
||||
flake8
|
||||
isort
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
django==2.2.*
|
||||
Pillow
|
Loading…
Reference in a new issue