Add documentation and source

Added documentation, source and extra files.
This commit is contained in:
2025-07-02 20:26:50 +02:00
parent 4fc1d36a10
commit e3ebf6bf4f
295 changed files with 24986 additions and 0 deletions

View File

@ -0,0 +1,9 @@
from django.apps import AppConfig
class DemonstrationConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "demonstration"
default_app_config = "demonstration.DemonstrationConfig"

View File

@ -0,0 +1,3 @@
from .person import PersonForm
from .search import SearchForm
from .upload import UploadForm

View File

@ -0,0 +1,13 @@
from datetime import date
from django import forms
class PersonForm(forms.Form):
"""Example of form for person information."""
first_name = forms.CharField(max_length=32, label="first name")
last_name = forms.CharField(max_length=32, label="last name")
birth_date = forms.DateField(initial=date(1990, 1, 1), label="birthday")
phone_number = forms.CharField(max_length=12, label="phone number")
password = forms.CharField(widget=forms.PasswordInput, max_length=50, label="password")

View File

@ -0,0 +1,24 @@
from typing import List
from django import forms
from django.core.exceptions import ValidationError
class SearchForm(forms.Form):
"""Example of search form."""
FORBIDDEN_WORDS: List[str] = ["lemon", "hat", "car"]
query = forms.CharField(max_length=32, label="query", required=True)
def clean_query(self) -> str:
"""
Validate the query field.
Returns:
The value for the "cleaned" query field.
"""
value: str = self.cleaned_data["query"]
if value.lower() in self.FORBIDDEN_WORDS:
raise ValidationError(f"Search term cannot be one of the following: {self.FORBIDDEN_WORDS}")
return value

View File

@ -0,0 +1,26 @@
from django import forms
from django.core.files.storage import FileSystemStorage
from django.http import HttpRequest
class UploadForm(forms.Form):
"""Example of file upload form."""
image = forms.ImageField(max_length=128, required=True, label="image")
@staticmethod
def save_uploaded_file(request: HttpRequest) -> str:
"""
Custom method to process the upload of the image.
Args:
request: HTTP request.
Returns:
URL of the new uploaded image.
"""
storage = FileSystemStorage()
image = request.FILES["image"]
name = storage.save(None, image)
return storage.url(name)

View File

@ -0,0 +1,77 @@
:root {
--head-bg-color: #222;
--head-fg-color: #fff;
--head-ln-color: #3cf;
}
html, body {
height: 100%;
min-height: 100%;
width: 100%;
}
body {
margin: 0;
display: grid;
grid-template-areas: "header" "content" "footer";
grid-template-rows: auto 1fr auto;
grid-template-columns: 100%;
font-family: "Roboto", "Lucida Grande", "DejaVu Sans", "Bitstream Vera Sans", Verdana, Arial, sans-serif;
}
section#header {
grid-area: header;
}
section#content {
grid-area: content;
}
section#footer {
grid-area: footer;
}
section#header, section#footer {
background-color: var(--head-bg-color);
color: var(--head-fg-color);
}
section#header a, section#footer a {
color: var(--head-ln-color);
text-decoration: none;
}
div.body {
width: 1024px;
margin: 1.5em auto;
}
table.form-table {
width: 100%;
}
table.form-table th {
text-align: left;
}
table.form-table td {
text-align: right;
}
table.form-table td > input[type=text] {
width: 100%;
box-sizing: border-box;
}
input[type=submit] {
padding: 0.5em 4em;
margin: 0;
background-color: crimson;
color: white;
font-size: 125%;
border: maroon 1px solid;
border-radius: 0.5em;
box-shadow: coral 0 0 0 1px inset;
}

View File

@ -0,0 +1,33 @@
{% load static %} {# The load tag enables template tags from other Django apps #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %} | Django Demonstration{% endblock title %}</title>
<link rel="stylesheet" href="{% static "demonstration/demonstration.css" %}">
</head>
<body>
<section id="header">
<div class="body">
<nav>
<a href="/">Home page</a>
</nav>
</div>
</section>
<section id="content">
<div class="body">
{% block body %}
Base content in a overridable block.
{% endblock body %}
</div>
</section>
<section id="footer">
<div class="body">
{% block footer %}
©2021 Steve Kossouho, <strong>Dawan</strong>
{% endblock footer %}
</div>
</section>
</body>
</html>

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Forms demonstration</title>
</head>
<body>
<h1>Sections of form rendering</h1>
<ul>
<li><a href="{% url "search" %}">Search form</a></li>
<li><a href="{% url "person" %}">Person fields form</a></li>
<li><a href="{% url "upload" %}">Upload form</a></li>
</ul>
</body>
</html>

View File

@ -0,0 +1,15 @@
{% extends "demonstration/base.html" %}
{% block body %}
<form action="" method="post" name="person-form">
{% csrf_token %}
<table class="form-table">
{{ form.as_table }}
<tr>
<th></th>
<td><input type="submit" name="submit-form" value="Validate"></td>
</tr>
</table>
</form>
<hr>
{% endblock body %}

View File

@ -0,0 +1,22 @@
{% extends "demonstration/base.html" %}
{% block body %}
<form action="" method="get" name="search-form">
<table class="form-table">
{{ form.as_table }}
<tr>
<th></th>
<td><input type="submit" name="submit-form" value="Search"></td>
</tr>
</table>
</form>
<hr>
<em>{{ results|length }} results.</em>
<ul>
{% for item in results %}
<li>{{ item }}</li>
{% empty %}
<li>No item found.</li>
{% endfor %}
</ul>
{% endblock body %}

View File

@ -0,0 +1,21 @@
{% extends "demonstration/base.html" %}
{% block body %}
<form action="" method="post" name="upload-form" enctype="multipart/form-data">
{% csrf_token %}
<table class="form-table">
{{ form.as_table }}
<tr>
<th></th>
<td><input type="submit" name="submit-form" value="Upload file"></td>
</tr>
</table>
</form>
<hr>
{% if image_url %}
The image was successfully uploaded at <a href="{{ image_url }}">{{ image_url }}</a>
<p>
<img src="{{ image_url }}" alt="Uploaded image">
</p>
{% endif %}
{% endblock body %}

View File

@ -0,0 +1,9 @@
from django.urls import path
from demonstration.views import view_search_form, view_person_form, view_upload_form
urlpatterns = [
path("search/", view_search_form, name="search"),
path("person/", view_person_form, name="person"),
path("upload/", view_upload_form, name="upload"),
]

View File

@ -0,0 +1,81 @@
from typing import List, Optional
from annoying.decorators import render_to
from django.http import HttpRequest, HttpResponseRedirect
from demonstration.forms import SearchForm, PersonForm, UploadForm
NAMES: List[str] = [
"Jean",
"Paul",
"Robert",
"Julien",
"Nicolas",
"François",
"Julie",
"Marie",
"Anne",
"Évelyne",
"Jeanne",
"Claire",
]
@render_to("demonstration/index.html")
def view_index(request: HttpRequest): # noqa
return {}
@render_to("demonstration/search_form_view.html")
def view_search_form(request: HttpRequest): # noqa
"""
View for the search form.
Args:
request: HTTP request.
Returns:
Data for rendering the template, as a context dictionary.
"""
form = SearchForm(request.GET) if request.GET else SearchForm()
results: List[str] = []
if form.is_valid():
query: str = form.cleaned_data["query"].lower()
results = [item for item in NAMES if query in item.lower()]
return {"form": form, "results": results}
@render_to("demonstration/person_form_view.html")
def view_person_form(request: HttpRequest): # noqa
"""
View for the person form.
Args:
request: HTTP request.
Returns:
Data for rendering the template, as a context dictionary.
"""
form = PersonForm(request.POST) if request.method == "POST" else PersonForm()
return {"form": form}
@render_to("demonstration/upload_form_view.html")
def view_upload_form(request: HttpRequest): # noqa
"""
View for the upload form.
Args:
request: HTTP request.
Returns:
Data for rendering the template, as a context dictionary.
"""
form = UploadForm(request.POST, request.FILES) if request.method == "POST" else UploadForm()
image_url: Optional[str] = None
if form.is_valid():
image_url = form.save_uploaded_file(request)
return {"form": form, "image_url": image_url}