Save teacher and redirect to teacher page
This commit is contained in:
parent
8776e6a8af
commit
63fd65fb5e
13 changed files with 176 additions and 74 deletions
|
@ -1,6 +0,0 @@
|
||||||
def main():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,54 +0,0 @@
|
||||||
import time
|
|
||||||
|
|
||||||
from django.test import LiveServerTestCase
|
|
||||||
from selenium import webdriver
|
|
||||||
from selenium.common.exceptions import WebDriverException
|
|
||||||
|
|
||||||
MAX_WAIT = 10
|
|
||||||
|
|
||||||
|
|
||||||
class NewVisitorTest(LiveServerTestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.browser = webdriver.Firefox()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.browser.quit()
|
|
||||||
|
|
||||||
def test_can_start_a_list_and_retrieve_it_later(self):
|
|
||||||
# Edith has received a mail from her librarian about a website
|
|
||||||
# she can use to tell the books she needs. She goes
|
|
||||||
# to check out its homepage
|
|
||||||
self.browser.get(self.live_server_url)
|
|
||||||
|
|
||||||
# She notices the page title and header mention "manuels"
|
|
||||||
self.assertIn('Manuels', self.browser.title)
|
|
||||||
|
|
||||||
# She is invited to enter her contact information (first name,
|
|
||||||
# last name and phone number)
|
|
||||||
# She types "Edith" into the first name text box
|
|
||||||
|
|
||||||
# She types "Doe" as her last name
|
|
||||||
|
|
||||||
# She types "0612345678" as her phone number
|
|
||||||
|
|
||||||
# When she hits enter, the page updates, and now the page displays
|
|
||||||
# her contact info on top and a form to enter book data
|
|
||||||
|
|
||||||
# Edith wonders whether the site will remember her books. Then she sees
|
|
||||||
# that the site has generated a unique URL for her -- there is some
|
|
||||||
# explanatory text to that effect.
|
|
||||||
|
|
||||||
# She visits that URL - her books list is still there.
|
|
||||||
|
|
||||||
# Satisfied, she goes back to sleep
|
|
||||||
self.fail('Finish the test!')
|
|
||||||
|
|
||||||
def wait_for(self, fn):
|
|
||||||
start_time = time.time()
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
return fn()
|
|
||||||
except (AssertionError, WebDriverException) as e:
|
|
||||||
if time.time() - start_time > MAX_WAIT:
|
|
||||||
raise e
|
|
||||||
time.sleep(0.5)
|
|
0
manuels/forms.py
Normal file
0
manuels/forms.py
Normal file
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 2.0.5 on 2018-05-21 18:07
|
# Generated by Django 2.0.5 on 2018-05-21 19:16
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
@ -15,6 +15,9 @@ class Migration(migrations.Migration):
|
||||||
name='Teacher',
|
name='Teacher',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('first_name', models.CharField(max_length=100)),
|
||||||
|
('last_name', models.CharField(max_length=100)),
|
||||||
|
('phone_number', models.CharField(max_length=10)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
74
manuels/migrations/0002_auto_20180521_2154.py
Normal file
74
manuels/migrations/0002_auto_20180521_2154.py
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
# Generated by Django 2.0.5 on 2018-05-21 19:54
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import manuels.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('manuels', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Book',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('field', models.CharField(max_length=100, verbose_name='matière')),
|
||||||
|
('title', models.TextField(verbose_name='titre')),
|
||||||
|
('authors', models.TextField(verbose_name='auteurs')),
|
||||||
|
('editor', models.CharField(max_length=200, verbose_name='éditeur')),
|
||||||
|
('collection', models.CharField(blank=True, max_length=200, verbose_name='collection')),
|
||||||
|
('publication_year', models.PositiveIntegerField(verbose_name='année de publication')),
|
||||||
|
('isbn', models.TextField(validators=[manuels.models.isbn_validator], verbose_name='ISBN/EAN')),
|
||||||
|
('price', models.PositiveIntegerField(verbose_name='prix')),
|
||||||
|
('previously_acquired', models.BooleanField(verbose_name="manuel acquis précédemment par l'élève")),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'livre',
|
||||||
|
'verbose_name_plural': 'livres',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Level',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=10, verbose_name='nom')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'classe',
|
||||||
|
'verbose_name_plural': 'classe',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='teacher',
|
||||||
|
options={'verbose_name': 'enseignant', 'verbose_name_plural': 'enseignants'},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='teacher',
|
||||||
|
name='first_name',
|
||||||
|
field=models.CharField(max_length=100, verbose_name='prénom'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='teacher',
|
||||||
|
name='last_name',
|
||||||
|
field=models.CharField(max_length=100, verbose_name='nom'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='teacher',
|
||||||
|
name='phone_number',
|
||||||
|
field=models.CharField(max_length=10, verbose_name='numéro de téléphone'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='book',
|
||||||
|
name='level',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='manuels.Level'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='book',
|
||||||
|
name='teacher',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='manuels.Teacher'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,6 +1,51 @@
|
||||||
|
import re
|
||||||
|
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
class Teacher(models.Model):
|
class Teacher(models.Model):
|
||||||
# first_name = models.CharField()
|
class Meta:
|
||||||
pass
|
verbose_name = 'enseignant'
|
||||||
|
verbose_name_plural = 'enseignants'
|
||||||
|
first_name = models.CharField('prénom', max_length=100)
|
||||||
|
last_name = models.CharField('nom', max_length=100)
|
||||||
|
phone_number = models.CharField('numéro de téléphone', max_length=10)
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
from django.urls import reverse
|
||||||
|
return reverse('add_book', args=[str(self.id)])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def full_name(self):
|
||||||
|
return f'{self.first_name} {self.last_name}'
|
||||||
|
|
||||||
|
|
||||||
|
class Level(models.Model):
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'classe'
|
||||||
|
verbose_name_plural = 'classe'
|
||||||
|
name = models.CharField('nom', max_length=10)
|
||||||
|
|
||||||
|
|
||||||
|
def isbn_validator(value):
|
||||||
|
regex = re.compile(r'(\d-?){10,13}X?')
|
||||||
|
if not regex.match(value):
|
||||||
|
raise ValidationError("%(value)s n'est pas un ISBN valide.", params={'value': value})
|
||||||
|
|
||||||
|
|
||||||
|
class Book(models.Model):
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'livre'
|
||||||
|
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)
|
||||||
|
field = models.CharField('matière', max_length=100)
|
||||||
|
title = models.TextField('titre')
|
||||||
|
authors = models.TextField('auteurs')
|
||||||
|
editor = models.CharField('éditeur', max_length=200)
|
||||||
|
collection = models.CharField('collection', max_length=200, blank=True)
|
||||||
|
publication_year = models.PositiveIntegerField('année de publication')
|
||||||
|
isbn = models.TextField('ISBN/EAN', validators=[isbn_validator])
|
||||||
|
price = models.PositiveIntegerField('prix')
|
||||||
|
previously_acquired = models.BooleanField("manuel acquis précédemment par l'élève")
|
||||||
|
|
13
manuels/templates/manuels/add_book.html
Normal file
13
manuels/templates/manuels/add_book.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{% extends 'manuels/base.html' %}
|
||||||
|
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
|
||||||
|
{% block title %}Ajouter un livre{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
Bienvenue {{ teacher.full_name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -3,6 +3,8 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Manuels - {% block title %}{% endblock %}</title>
|
<title>Manuels - {% block title %}{% endblock %}</title>
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|
|
@ -1,6 +1,19 @@
|
||||||
{% extends 'manuels/base.html' %}
|
{% extends 'manuels/base.html' %}
|
||||||
|
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
|
||||||
{% block title %}Accueil{% endblock %}
|
{% block title %}Accueil{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<form action="" method="post" class="form">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form form %}
|
||||||
|
{% buttons %}
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
{% endbuttons %}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,7 +0,0 @@
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
|
|
||||||
class HomePageTest(TestCase):
|
|
||||||
def test_home_page_returns_correct_html(self):
|
|
||||||
response = self.client.get('/')
|
|
||||||
self.assertTemplateUsed(response, 'manuels/home_page.html')
|
|
7
manuels/urls.py
Normal file
7
manuels/urls.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from manuels.views import AddBookView
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('teacher/<int:id>/', AddBookView.as_view(), name='add_book')
|
||||||
|
]
|
|
@ -1,9 +1,20 @@
|
||||||
from django.views.generic import CreateView
|
from django.shortcuts import get_object_or_404
|
||||||
|
from django.views.generic import CreateView, FormView, TemplateView
|
||||||
|
|
||||||
from manuels.models import Teacher
|
from manuels.models import Teacher
|
||||||
|
|
||||||
|
|
||||||
class HomePageView(CreateView):
|
class HomePageView(CreateView):
|
||||||
model = Teacher
|
model = Teacher
|
||||||
fields = []
|
fields = ['first_name', 'last_name', 'phone_number']
|
||||||
template_name = 'manuels/home_page.html'
|
template_name = 'manuels/home_page.html'
|
||||||
|
|
||||||
|
|
||||||
|
class AddBookView(TemplateView):
|
||||||
|
template_name = 'manuels/add_book.html'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data()
|
||||||
|
context['teacher'] = get_object_or_404(Teacher, pk=self.kwargs['id'])
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
|
@ -14,11 +14,12 @@ Including another URLconf
|
||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
"""
|
"""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path
|
from django.urls import path, include
|
||||||
|
|
||||||
from manuels.views import HomePageView
|
from manuels.views import HomePageView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('', HomePageView.as_view(), name='home_page'),
|
path('', HomePageView.as_view(), name='home_page'),
|
||||||
|
path('', include('manuels.urls')),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue