MyGear - User-Bereich anlegen
Machen wir doch erst mal den Login/Logout und alles, was zum User gehört, etwas übersichtlicher.
Da die header.html (siehe hier) nicht getrennt aufgerufen wird, braucht sie auch keinen extends-Block.
<div class="header">
<div class="menubar">
<p><a href="{% url 'home' %}">MyGear</a></p>
</div>
<div class="user">
{% if user.is_authenticated %}
{% include "user.html" %}
{% else %}
{% block login %}
<p><a href="{% url 'login' %}">Login / Register</a></p>
{% endblock %}
{% endif %}
</div>
</div>
Was macht das Ganze? Im Header legt es eine Menüleiste an. Die hat bis jetzt nur den Eintrag, der zurück zur Startseite führt. Danach kommt ein User-Bereich. Der lädt entweder aus der user.html nach, wenn ein User eingeloggt ist - {% if user.is_authenticated %} - oder einfach einen Link zum Login, wenn nicht.
Die user.html lege ich im templates-Ordner meiner accounts-App an. Da mein Django-Projekt diese accounts-App kennt, muss ich nicht extra angeben, wo sie liegt. Der Übersicht halber, und weil sie dort thematisch am Besten hinpasst, kommt sie eben dort hin.
<div class="dropdown">
<button class="dropbtn">{{ display_name }}</button>
<div class="dropdown-content">
<a href="">User Profile</a>
<a href="">Change password</a>
<form action="{% url 'logout' %}" method="post">
{% csrf_token %}
<button type="submit" class="btn-link">Logout</button>
</form>
</div>
</div>
Was macht das denn nun?
Eine weitere CSS-Klasse, mehr dazu später, um einen Dropdown zu bekommen, wenn die Maus drüber fährt. Dort taucht dann später ein Link zum Benutzerprofil auf. Ebenso einer, um das Passwort zu ändern und einer zum Logout. Durch {{ display_name }} steht im Header dann bei eingeloggtem User der Name, aktuell noch auf einem Button. Um den dahin zu bekommen, muss ich den home-View in der views.py der home-App anpassen.
def home_view(request):
if request.user.is_authenticated:
if request.user.first_name=="":
display_name=request.user.last_name
if request.user.last_name=="":
display_name=request.user.email
else:
display_name=request.user.get_full_name
else:
display_name=""
context={'user':request.user,'display_name':display_name}
return render(request, 'home.html', context=context)
Das ist zwar etwas länger, macht aber nichts anderes, als eine zusätzliche Variable display_name anzulegen. Diese befüllt die Funktion mit dem Nachnamen, wenn der Vorname leer ist, mit der eMail-Adresse, wenn auch der Nachname leer ist. Ansonsten nimmt es den kompletten Namen. Und wenn kein User eingeloggt ist, wird die Variable mit Nichts befüllt, sonst existiert sie nicht und das Template meckert, wenn die Seite angezeigt wird. Bei mir taucht in dem Fall ja der Login-Link auf.
Jetzt ist alles drin, hübsch ist es aber noch nicht. Wird es auch nicht, aber bedienbar. Mit CSS. In meinem static-Order, der liegt direkt im Projekt, in dem auch die manage.py liegt, erstelle ich eine style.css. In der home.html kommt direkt in die erste Zeile: {% load static %}. Und in den head:
<link rel="stylesheet" href="{% static 'style.css' %}">
Es ändert sich aber noch nix. In die settings.py muss:
STATIC_URL = 'static/'
STATICFILES_DIRS = (
BASE_DIR / 'static',
)
Und natürlich muss in die style.css auch noch Inhalt.
/* Style the Header */
.header {
display: flex;
background-color: blanchedalmond;
}
/* Style the Main part */
.main {
margin: 1em;
display: flow-root;
}
/* Style the User section */
.user {
margin-left: auto;
margin-right: 0;
}
/* Style the dropdown */
.dropdown {
position: relative;
}
/* Style the dropdown button */
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
/* Dropdown content */
.dropdown-content {
right: 1px;
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 200px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
/* Links inside dropdown content */
.dropdown-content a {
text-align: center;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content a:hover {
background-color: #f1f1f1
}
/* Show the dropdown content on hover */
.dropdown:hover .dropdown-content {
display: block;
}
/* Change background color of dropdown button on hover */
.dropdown:hover .dropbtn {
background-color: #3e8e41;
}
/* Change button to link */
.btn-link {
border: none;
outline: none;
background: none;
cursor: pointer;
color: black;
width: 100%;
padding: 12px 16px;
text-decoration: none;
background-color: #f9f9f9;
display: block;
font-family: inherit;
font-size: inherit;
}
/* Change button to link on hover */
.btn-link:hover {
background-color: #f1f1f1
}
Was dabei rauskommt ist nicht hübsch. Es zeigt aber deutlich die einzelnen Komponenten und Funktionen, die ich bisher erstellt habe. Und ich sehe auf Anhieb, wenn etwas nicht stimmt. Damit steht auch fast das Grundgerüst. Im nächsten Abschnitt wird noch die Funktion zum Ändern des Passworts erstellt und damit ist der erste Teil mit dem User-Management auch fertig.