Self-hostable website analytics on Django: a straightforward collector API, dashboards, a world map, and PDF reports.
analyticsdjangodockerhandcodedpythonself-hostedsqliteviteweb-analytics
1{% extends "base.html" %}
2
3
4{% block breadcrumbs %}
5<nav aria-label="breadcrumb">
6 <ol class="breadcrumb mb-0">
7 <li class="breadcrumb-item"><a href="/">Home</a></li>
8 <li class="breadcrumb-item"><a href="{% url 'profile' %}">Profile</a></li>
9 <li class="breadcrumb-item active" aria-current="page">{{ title }}</li>
10 </ol>
11</nav>
12{% endblock %}
13
14
15{% block main %}
16<div class="container my-5">
17 <div class="row">
18 <div class="col-lg-6 offset-lg-3 col-md-8 offset-md-2">
19 <div class="section-label mb-2">account · security</div>
20 <h1 class="fw-bolder text-white" style="letter-spacing: -0.01em;">{{ title }}</h1>
21 <p class="text-muted small mb-4">Enter your current password, then your new password twice to confirm.</p>
22
23 <form method="POST">
24 {% csrf_token %}
25
26 {% if form.errors %}
27 <div class="alert alert-warning py-2 small">
28 {% if form.errors.items|length == 1 %}Please correct the error below.{% else %}Please correct the errors below.{% endif %}
29 </div>
30 {% endif %}
31
32 <div class="form-floating mb-3">
33 <input type="password" class="form-control {% if form.old_password.errors %}is-invalid{% endif %}" name="old_password" id="id_old_password" placeholder="Old password" autocomplete="current-password" required autofocus />
34 <label for="id_old_password">Old password</label>
35 {{ form.old_password.errors }}
36 </div>
37 <div class="form-floating mb-3">
38 <input type="password" class="form-control {% if form.new_password1.errors %}is-invalid{% endif %}" name="new_password1" id="id_new_password1" placeholder="New password" autocomplete="new-password" required />
39 <label for="id_new_password1">New password</label>
40 {% if form.new_password1.help_text %}
41 <div class="alert alert-info py-2 px-3 mt-2 small">{{ form.new_password1.help_text|safe }}</div>
42 {% endif %}
43 {{ form.new_password1.errors }}
44 </div>
45 <div class="form-floating mb-3">
46 <input type="password" class="form-control {% if form.new_password2.errors %}is-invalid{% endif %}" name="new_password2" id="id_new_password2" placeholder="Confirm new password" autocomplete="new-password" required />
47 <label for="id_new_password2">Confirm new password</label>
48 {{ form.new_password2.errors }}
49 </div>
50 <button type="submit" class="btn btn-primary">Change password →</button>
51 </form>
52 </div>
53 </div>
54</div>
55{% endblock %}