Commit c13db1b3 authored by Bonnegent Sebastien's avatar Bonnegent Sebastien
Browse files

cours 3 ok

parent c29fe294
......@@ -3,9 +3,7 @@
% version 2018
# Interface d'administration
## Prérequis
### garage/models.py
- Garage
- Vehicule
......@@ -31,7 +29,6 @@ Starting development server at http://127.0.0.1:8000/
~~~
## Consultation
### Adresse
- http://localhost:8000/
- http://localhost:8000/admin/
......@@ -237,6 +234,12 @@ path('accounts/', include('django.contrib.auth.urls')),
# ...
~~~
### conf/settings.py
~~~python
LOGOUT_REDIRECT_URL = '/'
LOGIN_REDIRECT_URL = '/'
~~~
### garage/templates/registration/login.html
- le template doit être présent
......
% Django par la pratique #03
% Sébastien Bonnegent
% https://framagit.org/bonnegent/cours\_django
% version 2018
# Sphinx
# Prérequis
## Prérequis
### Virtual Env
* source /opt/venv/django/bin/activate
* pipenv shell
## Mise en place
### sphinx-quickstart
~~~
$ mkdir docs && cd docs
$ sphinx-quickstart
Enter the root path for documentation.
> Root path for the documentation [.]:
> Separate source and build directories (y/n) [n]:
> Name prefix for templates and static dir [_]:
> Project name: FireWall Manager
> Author name(s): S.Bonnegent
> Project language [en]: fr
> Source file suffix [.rst]:
> Name of your master document (without suffix) [index]:
> Create Makefile? (y/n) [y]:
> Create Windows command file? (y/n) [y]:
~~~
## Utilisation
### Génération du html
~~~
$ make html
~~~
### Organisation des fichiers
\center\includegraphics[height=4.5cm]{images/tree-sphinx.png}
## Premiers fichiers #1
### docs/index.rst
~~~{.numberLines}
FireWall Manager
================
.. toctree::
:maxdepth: 2
about
### Base de départ
~~~
## Premiers fichiers #2
### docs/about.rst
~~~{.numberLines}
========
À propos
========
FWM permet de gérer des parefeux linux simple,
à partir de modèle, et de déployer directement
les règles.
~~~
# Consultation en ligne
## django-docs
### Prérequis
~~~
$ pip install django-docs
$ #!! settings.py et db.sqlite3 dans le dépôt !!
$ git clone \
git@gitlab.insa-rouen.fr:bonnegent/vehicules.git
$ cd vehicules
$ git checkout cours_3_debut
~~~
## Configuration #1
## Classe menu
### garage/views.py
~~~python
class MenuGarage(object):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['menu_garage'] = 'active'
return context
### conf/settings\_common.py
~~~{.py .numberLines}
INSTALLED_APPS = [
...
'webui',
'django_extensions',
'docs',
]
DOCS_ROOT = os.path.join(BASE_DIR, 'docs',
'_build', 'html')
class GarageList(MenuGarage, generic.ListView):
model = Garage
~~~
## Configuration #2
### conf/urls.py
~~~{.py .numberLines}
from django.conf.urls import include
# CRUD
## Create #1
### garage/views.py
~~~python
class GarageCreate(MenuGarage, edit.CreateView):
model = Garage
fields = ['nom', 'adresse', 'mail', 'telephone']
template_name = "garage/object_create.html"
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^docs/', include('docs.urls')),
]
def form_valid(self, form):
form.instance.createur = self.request.user
return super(GarageCreate, self).form_valid(form)
~~~
## Consultation
- http://127.0.0.1:8000/docs/
# Documentation
## Sphinx #1
### Prérequis
~~~
$ pip install pydotplus
## Create #2
### garage/templates/garage/object_create.html
~~~
### docs/conf.py
~~~{.py .numberLines}
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.inheritance_diagram']
{% extends "garage/home.html" %}
{% block content %}
<h1>Création</h1>
<form enctype="multipart/form-data" method="post">
{% csrf_token %}
<table class="table table-striped">
{{form.as_table}}
<tr><td colspan=2>
<button class="btn btn-primary btn-block"
type="submit"/>Enregistrer</button>
</td>
</tr></table>
</form>
{% endblock %}
~~~
## Sphinx #2
## Create #3
### garage/models.py
~~~python
from django.urls import reverse
### docs/index.rst
~~~{.numberLines}
FireWall Manager
================
class Garage(models.Model):
# ...
.. toctree::
:maxdepth: 2
about
modeles
def get_absolute_url(self):
# return reverse('garage:garage-detail',
# kwargs={'pk': self.pk})
return reverse('garage:garage-list')
~~~
## Sphinx #3
### docs/modeles.rst
~~~{.numberLines}
=======
Modèles
=======
.. image:: _static/graph_models_webui.png
:alt: fwm
Parefeu
=======
.. autoclass:: webui.models.Parefeu
:members:
:exclude-members: objects
...
## Create #4
### garage/urls.py
~~~python
path('garage/add/',
login_required(views.GarageCreate.as_view()),
name='garage-create'),
~~~
## Graphique des modèles #1
graphviz doit être installé au niveau du système.
### django extensions
### garage/templates/garage/garage_list.html
~~~
./manage.py graph_models webui \
--output docs/_static/graph_models_webui.png
<a href="{% url 'garage:garage-create' %}"
class="btn btn-success" role="button">Ajouter</a>
~~~
## Graphique des modèles #2
\center\includegraphics[height=6.5cm]{images/graph_models_webui.png}
## Docstring
### webui/models.py
~~~{.py .numberLines}
class Truc(models.Model):
"""Une définition courte...
:param toto: sert à truc (str)
:return: Truc()
"""
## Read #1
### garage/views.py
~~~python
class GarageDetail(MenuGarage, generic.DetailView):
model = Garage
~~~
## Gérer un numéro de version
### conf/settings_common.py
~~~{.py .numberLines}
VERSION = "0.1.171009"
## Read #2
### garage/templates/garage/garage_detail.html
~~~
### docs/conf.py
~~~{.py .numberLines}
import sys
import os
import django
sys.path.insert(0, os.path.abspath('..'))
os.environ['DJANGO_SETTINGS_MODULE'] = 'conf.settings'
django.setup()
from django.conf import settings
version = settings.VERSION
release = version
{% extends "garage/home.html" %}{% block content %}
<h1>{{ garage.nom }}</h1>
<table class="table table-striped"><tbody>
<tr><td>Adresse</td><td>{{ garage.adresse }}</td></tr>
<tr><td>Mail</td><td>{{ garage.mail }}</td></tr>
<tr><td>Téléphone</td><td>{{ garage.telephone }}</td></tr>
<tr><td>Créateur</td><td>{{ garage.createur }}</td></tr>
<tr><td colspan="2">
<a href="" class="btn btn-primary" role="button">Modifier</a>
<a href="" class="btn btn-danger" role="button">Supprimer</a>
</td></tr></tbody></table>
{% endblock %}
~~~
## Thème bootstrap #1
### Prérequis
~~~
$ pip install sphinx-bootstrap-theme
## Read #3
### garage/urls.py
~~~python
path('garage/<int:pk>/',
login_required(views.GarageDetail.as_view()),
name='garage-detail'),
~~~
### docs/conf.py
~~~{.py .numberLines}
import sphinx_bootstrap_theme
# html_theme = 'alabaster'
html_theme = 'bootstrap'
html_theme_path = \
sphinx_bootstrap_theme.get_html_theme_path()
## Update #1
### garage/views.py
~~~python
class GarageUpdate(MenuGarage, edit.UpdateView):
model = Garage
fields = ['nom', 'adresse', 'mail', 'telephone']
template_name = "garage/object_update.html"
~~~
## Thème bootstrap #2
~~~{.py .numberLines}
html_theme_options = {
'navbar_title': 'FWM',
'navbar_site_name': "Documentation",
'navbar_links': [(
'<span class="glyphicon glyphicon-home"></span>',
"/", True), ],
'navbar_sidebarrel': False,
'navbar_pagenav': False,
'navbar_pagenav_name': "Page",
'globaltoc_depth': 1,
'globaltoc_includehidden': "true",
'navbar_fixed_top': "true",
'source_link_position': "nav",
'bootstrap_version': "3",
}
## Update #2
### garage/templates/garage/object_update.html
~~~
## Version avec authentification
### conf/settings\_common.py
~~~{.py .numberLines}
DOCS_ACCESS = 'login_required'
{% extends "garage/home.html" %}
{% block content %}
<h1>Modification</h1>
<form enctype="multipart/form-data" method="post">
{% csrf_token %}<table class="table table-striped">
{{form.as_table}}
<tr><td colspan=2>
<button class="btn btn-primary btn-block"
type="submit"/>Modifier</button>
</td></tr>
</table>
</form>
{% endblock %}
~~~
## Authentification Django #1
### conf/urls.py
~~~
url(r'^accounts/',
include('django.contrib.auth.urls')),
## Update #3
### garage/urls.py
~~~python
path('garage/<int:pk>/update/',
login_required(views.GarageUpdate.as_view()),
name='garage-update'),
~~~
### Liens créés
~~~{.py .numberLines}
^login/$
^logout/$
^password_change/$
^password_change/done/$
^password_reset/$
^password_reset/done/$
^reset/...)/$
^reset/done/$
## Delete #1
### garage/views.py
~~~python
from django.urls import reverse_lazy
class GarageDelete(MenuGarage, edit.DeleteView):
model = Garage
success_url = reverse_lazy('garage:garage-list')
~~~
## Authentification Django #2
### conf/settings\_common.py
~~~{.py .numberLines}
TEMPLATES = [
...
'DIRS': [os.path.join(BASE_DIR,
'templates')],
...
## Delete #2
### garage/templates/garage/garage_confirm_delete.html
~~~
## Authentification Django #3
### webui/templates/registration/login.html
~~~{.py .numberLines}
{% extends "webui/base.html" %}
{% extends "garage/home.html" %}
{% block content %}
<form method="post"
action="{% url 'login' %}">
...
{% endblock %}
~~~
<h1>Suppression</h1><form method="post">{% csrf_token %}
<p>Êtes-vous sûr de vouloir supprimer le garage '{{ object.nom }}' ?</p>
<a href="{% url 'garage:garage-detail' object.pk %}"
class="btn btn-primary" role="button">Annuler</a>
<button class="btn btn-danger" type="submit"/>Supprimer</button>
</form>
{% endblock %}
~~~
## Delete #3
### garage/urls.py
~~~python
path('garage/<int:pk>/delete/',
login_required(views.GarageDelete.as_view()),
name='garage-delete'),
~~~
# TODO
## À faire: Partie véhicule
* création
* lecture
* modification
* suppression
No preview for this file type
{% load staticfiles %}
<!DOCTYPE html>
<html lang="fr">
<head>
<link rel="shortcut icon" href="{% static 'webui/images/favicon.ico' %}"/>
<title>FWM</title>
</head>
<body>
{# Load the tag library #}
{% load bootstrap3 %}
{# Load CSS and JavaScript #}
{% bootstrap_css %}
{% bootstrap_javascript %}
{# Display django.contrib.messages as Bootstrap alerts #}
{% bootstrap_messages %}
{# La barre de navigation #}
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a href="{% url 'index' %}" class="navbar-brand">FWM</a>
<button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#navbar-main">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse" id="navbar-main">
{% if user.is_authenticated %}
<ul class="nav navbar-nav">
{% if user.is_staff %}
<li><a href="/admin/">Administration</a></li>
{% endif %}
<li><a href="/docs/">Documentation</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'logout' %}">
<span class="glyphicon glyphicon-remove-circle"></span>
</a></li>
</ul>
{% else %}
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'login' %}">
<span class="glyphicon glyphicon-log-in"></span>
Connexion</a></li>
</ul>
{% endif %}
</div>
</div>
</div>
<div class="container">
<div class="page-header" id="banner">
<div class="row">
<h1>{% block title %}Accueil{% endblock %}</h1>
</div>
</div>
{% block content %}
<p>Texte d'accueil par défaut.</p>
{% endblock %}
</div>
</body>
</html>
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# FireWall Manager documentation build configuration file, created by
# sphinx-quickstart on Tue Oct 3 13:45:49 2017.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import sys
import os
import django
sys.path.insert(0, os.path.abspath('..'))
os.environ['DJANGO_SETTINGS_MODULE'] = 'conf.settings'
django.setup()
from django.conf import settings
# bootstrap
import sphinx_bootstrap_theme
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.inheritance_diagram']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'FireWall Manager'
copyright = '2017, S.Bonnegent - version %s' % settings.VERSION
author = 'S.Bonnegent'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
# version = '0.1'
version = settings.VERSION
# The full version, including alpha/beta/rc tags.
# release = 'a'
release = version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'fr'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
#html_theme = 'alabaster'
html_theme = 'bootstrap'
html_theme_path = sphinx_bootstrap_theme.get_html_theme_path()
html_title = "Docs"
html_favicon = os.path.join("..", "webui", "static", "webui", "images",
"favicon.ico")
html_theme_options = {
'navbar_title': 'FWM',
'navbar_site_name': "Documentation",
'navbar_links': [(
'<span class="glyphicon glyphicon-home"></span>',
"/", True), ],
'navbar_sidebarrel': False,
'navbar_pagenav': False,
'navbar_pagenav_name': "Page",
'globaltoc_depth': 1,
'globaltoc_includehidden': "true",
'navbar_fixed_top': "true",
'source_link_position': "nav",
'bootswatch_theme': "flatly",
'bootstrap_version': "3",
}
html_show_sourcelink = False
html_show_sphinx = False
# Theme options are theme-specific and customize the look and feel of a theme