Wrapping up
This commit is contained in:
parent
5a5eefa134
commit
63b67e9a9a
12 changed files with 211 additions and 21 deletions
|
@ -1,3 +1,18 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
# Register your models here.
|
from manuels.models import Teacher, Book, Level
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Teacher)
|
||||||
|
class TeacherAdmin(admin.ModelAdmin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Level)
|
||||||
|
class LevelAdmin(admin.ModelAdmin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Book)
|
||||||
|
class BookAdmin(admin.ModelAdmin):
|
||||||
|
pass
|
||||||
|
|
|
@ -7,3 +7,5 @@ class AddBookForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Book
|
model = Book
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
add_another = forms.BooleanField(label='Ajouter un autre livre', required=False)
|
||||||
|
|
24
manuels/migrations/0003_auto_20180521_2225.py
Normal file
24
manuels/migrations/0003_auto_20180521_2225.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Generated by Django 2.0.5 on 2018-05-21 20:25
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('manuels', '0002_auto_20180521_2154'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='book',
|
||||||
|
name='level',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='manuels.Level', verbose_name='classe'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='book',
|
||||||
|
name='teacher',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='manuels.Teacher', verbose_name='enseignant'),
|
||||||
|
),
|
||||||
|
]
|
19
manuels/migrations/0004_auto_20180521_2226.py
Normal file
19
manuels/migrations/0004_auto_20180521_2226.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 2.0.5 on 2018-05-21 20:26
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import manuels.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('manuels', '0003_auto_20180521_2225'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='book',
|
||||||
|
name='isbn',
|
||||||
|
field=models.CharField(max_length=20, validators=[manuels.models.isbn_validator], verbose_name='ISBN/EAN'),
|
||||||
|
),
|
||||||
|
]
|
17
manuels/migrations/0005_auto_20180521_2230.py
Normal file
17
manuels/migrations/0005_auto_20180521_2230.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Generated by Django 2.0.5 on 2018-05-21 20:30
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('manuels', '0004_auto_20180521_2226'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='level',
|
||||||
|
options={'verbose_name': 'classe', 'verbose_name_plural': 'classes'},
|
||||||
|
),
|
||||||
|
]
|
18
manuels/migrations/0006_auto_20180521_2307.py
Normal file
18
manuels/migrations/0006_auto_20180521_2307.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.0.5 on 2018-05-21 21:07
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('manuels', '0005_auto_20180521_2230'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='book',
|
||||||
|
name='previously_acquired',
|
||||||
|
field=models.BooleanField(choices=[(True, 'Oui'), (False, 'Non')], verbose_name="manuel acquis précédemment par l'élève"),
|
||||||
|
),
|
||||||
|
]
|
|
@ -20,13 +20,19 @@ class Teacher(models.Model):
|
||||||
def full_name(self):
|
def full_name(self):
|
||||||
return f'{self.first_name} {self.last_name}'
|
return f'{self.first_name} {self.last_name}'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.full_name
|
||||||
|
|
||||||
|
|
||||||
class Level(models.Model):
|
class Level(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = 'classe'
|
verbose_name = 'classe'
|
||||||
verbose_name_plural = 'classe'
|
verbose_name_plural = 'classes'
|
||||||
name = models.CharField('nom', max_length=10)
|
name = models.CharField('nom', max_length=10)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
def isbn_validator(value):
|
def isbn_validator(value):
|
||||||
regex = re.compile(r'(\d-?){10,13}X?')
|
regex = re.compile(r'(\d-?){10,13}X?')
|
||||||
|
@ -38,14 +44,29 @@ class Book(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = 'livre'
|
verbose_name = 'livre'
|
||||||
verbose_name_plural = 'livres'
|
verbose_name_plural = 'livres'
|
||||||
teacher = models.ForeignKey(to=Teacher, on_delete=models.SET_NULL, null=True)
|
|
||||||
level = models.ForeignKey(to=Level, on_delete=models.SET_NULL, null=True)
|
teacher = models.ForeignKey(verbose_name='enseignant', to=Teacher, on_delete=models.SET_NULL, null=True)
|
||||||
|
level = models.ForeignKey(verbose_name='classe', to=Level, on_delete=models.SET_NULL, null=True)
|
||||||
field = models.CharField('matière', max_length=100)
|
field = models.CharField('matière', max_length=100)
|
||||||
title = models.TextField('titre')
|
title = models.TextField('titre')
|
||||||
authors = models.TextField('auteurs')
|
authors = models.TextField('auteurs')
|
||||||
editor = models.CharField('éditeur', max_length=200)
|
editor = models.CharField('éditeur', max_length=200)
|
||||||
collection = models.CharField('collection', max_length=200, blank=True)
|
collection = models.CharField('collection', max_length=200, blank=True)
|
||||||
publication_year = models.PositiveIntegerField('année de publication')
|
publication_year = models.PositiveIntegerField('année de publication')
|
||||||
isbn = models.TextField('ISBN/EAN', validators=[isbn_validator])
|
isbn = models.CharField('ISBN/EAN', max_length=20, validators=[isbn_validator])
|
||||||
price = models.PositiveIntegerField('prix')
|
price = models.PositiveIntegerField('prix')
|
||||||
previously_acquired = models.BooleanField("manuel acquis précédemment par l'élève", blank=True)
|
YES_NO_CHOICE = (
|
||||||
|
(True, 'Oui'),
|
||||||
|
(False, 'Non'),
|
||||||
|
)
|
||||||
|
previously_acquired = models.BooleanField("manuel acquis précédemment par l'élève", choices=YES_NO_CHOICE, blank=False)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def previously_acquired_emoji(self):
|
||||||
|
if self.previously_acquired:
|
||||||
|
return '✅'
|
||||||
|
else:
|
||||||
|
return '🚫'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self.title} ({self.authors}) - {self.isbn}'
|
||||||
|
|
|
@ -2,17 +2,12 @@
|
||||||
|
|
||||||
{% load bootstrap4 %}
|
{% load bootstrap4 %}
|
||||||
|
|
||||||
{% block title %}Ajouter un livre{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
Bienvenue {{ teacher.full_name }}
|
<h1>Bienvenue {{ teacher.full_name }}</h1>
|
||||||
</div>
|
<h2>{% block title %}Ajouter un livre{% endblock %}</h2>
|
||||||
</div>
|
<form action="" method="post" class="form">
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<form action="#" method="post" class="form">
|
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% bootstrap_form form %}
|
{% bootstrap_form form %}
|
||||||
{% buttons %}
|
{% buttons %}
|
||||||
|
|
|
@ -8,6 +8,11 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
{% for message in messages %}
|
||||||
|
<div class="alert alert-{{ message.tags }} fade show" role="alert">
|
||||||
|
{{ message }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
47
manuels/templates/manuels/list_books.html
Normal file
47
manuels/templates/manuels/list_books.html
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
{% extends 'manuels/base.html' %}
|
||||||
|
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h1>Bienvenue {{ teacher.full_name }}</h1>
|
||||||
|
<h2>{% block title %}Liste des livres demandés{% endblock %}</h2>
|
||||||
|
<a href="{% url 'add_book' id=teacher.pk %}" class="btn btn-primary">Ajouter un livre</a>
|
||||||
|
<table class="table table-hover table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Classe</th>
|
||||||
|
<th scope="col">Matière</th>
|
||||||
|
<th scope="col">Titre</th>
|
||||||
|
<th scope="col">Auteurs</th>
|
||||||
|
<th scope="col">Éditeur</th>
|
||||||
|
<th scope="col">Collection</th>
|
||||||
|
<th scope="col">Année de publication</th>
|
||||||
|
<th scope="col">ISBN</th>
|
||||||
|
<th scope="col">Prix</th>
|
||||||
|
<th scope="col">Déjà acheté par l'élève</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for book in books %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{{ forloop.counter }}</th>
|
||||||
|
<td>{{ book.level }}</td>
|
||||||
|
<td>{{ book.field }}</td>
|
||||||
|
<td>{{ book.title }}</td>
|
||||||
|
<td>{{ book.authors }}</td>
|
||||||
|
<td>{{ book.editor }}</td>
|
||||||
|
<td>{{ book.collection }}</td>
|
||||||
|
<td>{{ book.publication_year }}</td>
|
||||||
|
<td>{{ book.isbn }}</td>
|
||||||
|
<td>{{ book.price }}</td>
|
||||||
|
<td>{{ book.previously_acquired_emoji }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -1,7 +1,8 @@
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from manuels.views import AddBookView
|
from manuels.views import AddBookView, ListBooksView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('teacher/<int:id>/', AddBookView.as_view(), name='add_book')
|
path('teacher/<int:id>/add', AddBookView.as_view(), name='add_book'),
|
||||||
|
path('teacher/<int:id>/', ListBooksView.as_view(), name='list_books'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
from django.contrib import messages
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.views.generic import CreateView, FormView, TemplateView
|
from django.urls import reverse
|
||||||
|
from django.views.generic import CreateView, ListView
|
||||||
|
|
||||||
from manuels.forms import AddBookForm
|
from manuels.forms import AddBookForm
|
||||||
from manuels.models import Teacher, Book
|
from manuels.models import Teacher, Book
|
||||||
|
@ -11,10 +13,7 @@ class HomePageView(CreateView):
|
||||||
template_name = 'manuels/home_page.html'
|
template_name = 'manuels/home_page.html'
|
||||||
|
|
||||||
|
|
||||||
class AddBookView(CreateView):
|
class BaseTeacherView:
|
||||||
model = Book
|
|
||||||
template_name = 'manuels/add_book.html'
|
|
||||||
form_class = AddBookForm
|
|
||||||
teacher = None
|
teacher = None
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
@ -27,6 +26,22 @@ class AddBookView(CreateView):
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class ListBooksView(BaseTeacherView, ListView):
|
||||||
|
model = Book
|
||||||
|
template_name = 'manuels/list_books.html'
|
||||||
|
context_object_name = 'books'
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Book.objects.filter(teacher=self.teacher)
|
||||||
|
|
||||||
|
|
||||||
|
class AddBookView(BaseTeacherView, CreateView):
|
||||||
|
model = Book
|
||||||
|
template_name = 'manuels/add_book.html'
|
||||||
|
form_class = AddBookForm
|
||||||
|
add_another = False
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
return {
|
return {
|
||||||
'teacher': self.teacher
|
'teacher': self.teacher
|
||||||
|
@ -36,3 +51,14 @@ class AddBookView(CreateView):
|
||||||
form = super().get_form(form_class)
|
form = super().get_form(form_class)
|
||||||
form.fields['teacher'].queryset = Teacher.objects.filter(pk=self.teacher.pk)
|
form.fields['teacher'].queryset = Teacher.objects.filter(pk=self.teacher.pk)
|
||||||
return form
|
return form
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
self.add_another = form.cleaned_data['add_another']
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
messages.success(self.request, f'"{self.object}" a été ajouté.')
|
||||||
|
if self.add_another:
|
||||||
|
return reverse('add_book', args=[str(self.teacher.id)])
|
||||||
|
else:
|
||||||
|
return reverse('list_books', args=[str(self.teacher.id)])
|
||||||
|
|
Loading…
Reference in a new issue