Erstellen von Datenprodukten mit Python: Hinzufügen der Benutzerverwaltung zu einer Django-Website

Dies ist das zweite Tutorial in unserer Reihe zum Erstellen von Datenprodukten mit Python. Merken Sie sich das als Leitmotiv Wir möchten eine webbasierte Website für Weinbewertungen und -empfehlungen mit Python-Technologien wie Django und Pandas erstellen. Wir haben uns entschieden, eine Website für Weinbewertungen und -empfehlungen zu erstellen, aber die Konzepte und der Technologie-Stack können auf alle Benutzerbewertungen und Empfehlungsprodukte angewendet werden.

Wir möchten, dass diese Tutorials Ihnen ein Produkt hinterlassen, das Sie anpassen und als Teil Ihres Portfolios zeigen können. Mit diesem Ziel vor Augen erklären wir Ihnen, wie Sie a einrichten Kodierung virtuelle Maschine und verwenden Sie sie als Django und Pandas + Scikit-lernen Python-Entwicklungsserver.

Im ersten Tutorial haben wir ein Django-Projekt und eine Django-App für unsere Wine-Recommender-Webanwendung gestartet. Das Ganze wird ein inkrementeller Prozess sein, dem Sie folgen können, indem Sie einzelne Tags in unserem auschecken GitHub-Repository. Auf diese Weise können Sie in einem bestimmten Stadium diejenigen Einzelaufgaben bearbeiten, die Sie interessanter oder schwieriger finden.

In diesem zweiten Tutorial werden wir die Benutzerverwaltung hinzufügen. Dies ist ein wichtiger Teil. Sobald wir in der Lage sind, einzelne Benutzer zu identifizieren, sind wir bereit, Benutzerempfehlungen durch maschinelles Lernen zu generieren.

Das dritte Tutorial zeigt Ihnen, wie Sie maschinelles Lernen verwenden, um unseren Benutzern mithilfe von k-Means-Clustering Weinvorschläge zu machen.

Denken Sie daran, dass Sie dem Tutorial in jeder Entwicklungsphase folgen können, indem Sie forken das Repo in Ihr eigenes GitHub-Konto, klonen Sie es dann in Ihren Arbeitsbereich und checken Sie das entsprechende Tag aus. Indem Sie das Repo forken, können Sie es nach Belieben ändern und so viel damit experimentieren, wie Sie möchten. Wenn Sie zu irgendeinem Zeitpunkt Lust haben, ein wenig Hilfe bei einem Schritt des Tutorials zu haben oder es zu Ihrem eigenen zu machen, können wir eine 1: 1-Codementor-Sitzung darüber veranstalten.

Also lasst uns mit unserem Projekt fortfahren!

Konfigurieren der Django-Authentifizierung

Von dem Moment an, als wir unser Projekt mit erstellt haben django-admin startprojectwurden alle Module zur Benutzerauthentifizierung aktiviert. Diese bestehen aus zwei Artikeln, die in unserem aufgeführt sind INSTALLED_APPS in settings.py:

  • django.contrib.auth enthält den Kern des Authentifizierungsframeworks und seine Standardmodelle.
  • django.contrib.contenttypes ist das Inhaltstypsystem von Django, mit dem Berechtigungen mit von Ihnen erstellten Modellen verknüpft werden können.

und diese Artikel in Ihrem MIDDLEWARE_CLASSES Einstellung:

  • SessionMiddleware verwaltet Sitzungen über Anforderungen hinweg.
  • AuthenticationMiddleware ordnet Benutzer Anfragen mithilfe von Sitzungen zu.
  • SessionAuthenticationMiddleware meldet Benutzer nach einer Kennwortänderung von ihren anderen Sitzungen ab.

Mit diesen Einstellungen, als wir den Befehl ausgeführt haben manage.py migrate Wir haben bereits die notwendigen Datenbanktabellen für authentifizierungsbezogene Modelle und Berechtigungen für alle Modelle erstellt, die in unseren installierten Apps definiert sind. Tatsächlich können wir sie auf der Admin-Site im Abschnitt Benutzer sehen.

Aber wir wollen mindestens zwei Dinge tun. Zunächst möchten wir für einige Aktionen in unserer Web-App eine Authentifizierung verlangen (z. B. beim Hinzufügen einer neuen Weinbewertung). Zweitens möchten wir, dass Benutzer sich über unsere Web-App (und nicht über die Admin-Site) registrieren und anmelden können.

Beschränken des Zugriffs auf angemeldete Benutzer

Nehmen wir jetzt an, dass wir Benutzer einfach über die Admin-Oberfläche erstellen können. Gehen Sie dorthin und erstellen Sie einen Benutzer, den wir in diesem Abschnitt verwenden werden. Wenn wir in letzter Zeit die Admin-Oberfläche verwendet haben, werden wir wahrscheinlich weiterhin als Admin angemeldet sein. Das ist erstmal ok.

Als nächstes wollen wir den Zugriff auf unsere einschränken add_review anzeigen, sodass nur angemeldete Benutzer sie verwenden können.

Die saubere und elegante Möglichkeit, den Zugriff auf Ansichten einzuschränken, ist die Verwendung von @login_required Anmerkung. Modifiziere den add_review Funktion ein reviews/views.py also sieht es so aus:

@login_required
def add_review(request, wine_id):
    wine = get_object_or_404(Wine, pk=wine_id)
    form = ReviewForm(request.POST)
    if form.is_valid():
        rating = form.cleaned_data['rating']
        comment = form.cleaned_data['comment']
        user_name = form.cleaned_data['user_name']
        user_name = request.user.username
        review = Review()
        review.wine = wine
        review.user_name = user_name
        review.rating = rating
        review.comment = comment
        review.pub_date = datetime.datetime.now()
        review.save()
        
        
        
        return HttpResponseRedirect(reverse('reviews:wine_detail', args=(wine.id,)))
    
    return render(request, 'reviews/wine_detail.html', {'wine': wine, 'form': form})

Wir haben zwei Modifikationen vorgenommen. Die erste besteht darin, die hinzuzufügen @login_required Anmerkung. Damit erlauben wir den Zugriff auf diese Ansichtsfunktion nur eingeloggten Benutzern. Die zweite ist zu verwenden request.user.username als Benutzername für unsere Bewertungen. Das Anforderungsobjekt hat eine Referenz auf den aktiven Benutzer, und diese Instanz hat eine username Feld, das wir bei Bedarf verwenden können.

Da wir das Benutzernamensfeld im Formular nicht mehr benötigen, können wir diese Formularklasse in ändern reviews/forms.py folgendermaßen.

class ReviewForm(ModelForm):
    class Meta:
        model = Review
        fields = ['rating', 'comment']
        widgets = {
            'comment': Textarea(attrs={'cols': 40, 'rows': 15}),
        }

Geben Sie hier die Bildbeschreibung ein

Wenn der Benutzer nicht angemeldet ist, wird der Benutzer auf eine Anmeldeseite umgeleitet. Sie können dies versuchen, indem Sie sich von der Admin-Seite abmelden und dann versuchen, eine Weinbewertung hinzuzufügen.

Wenn Sie das versuchen, sehen Sie a Page not found (404) Fehler, da wir keine URL-Zuordnung zur Anmeldeseitenanforderung und auch keine Vorlage dafür definiert haben. Beachten Sie auch, dass die URL, zu der Sie umgeleitet werden, a enthält next=... param Dies ist die Zielseite, nachdem wir uns ordnungsgemäß angemeldet haben.

Anmeldeansichten

Django bietet mehrere Ansichten, die Sie für die Anmeldung, Abmeldung und Passwortverwaltung verwenden können. Wir werden sie hier verwenden. Also das Wichtigste zuerst. Ändere das urlpatterns Liste ein winerama/urls.py und belasse es wie folgt.

urlpatterns = [
    url(r'^reviews/', include('reviews.urls', namespace="reviews")),
    url(r'^admin/', include(admin.site.urls)),
    url('^accounts/', include('django.contrib.auth.urls'))
]

Wir haben gerade alle Mappings aus importiert django.contrib.auth.urls. Jetzt brauchen wir Vorlagen für verschiedene Webseiten zur Benutzerverwaltung. Sie müssen eingelegt werden templates/registration im Stammordner für unser Django-Projekt.

Erstellen Sie dort beispielsweise eine login.html Vorlage mit folgendem Code:

{% extends 'base.html' %}
{% load bootstrap3 %}


{% block title %}
<h2>Login</h2>
{% endblock %}

{% block content %}
<form action="{% url 'auth:login' %}" method="post" class="form">
    {% csrf_token %}
    {% bootstrap_form form layout="inline" %}
    {% buttons %}
    <button type="submit" class="btn btn-primary">
      {% bootstrap_icon "user" %} Login
    </button>
    {% endbuttons %}
</form>
{% endblock %}

Damit unsere Vorlagen verfügbar sind, müssen wir die ändern TEMPLATES Liste ein winerama/settings.py um diesen Ordner einzuschließen.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Geben Sie hier die Bildbeschreibung ein

Wir müssen Vorlagen für jede Benutzerverwaltungsansicht erstellen. In diesem Abschnitt stellen wir nur zwei vor: templates/registration/login.html und ‘templates/registration/logged_out.html’. Wir werden auch die verschieben reviews/templates/reviews/base.html Vorlage zur Hauptsache templates/base.html Ordner, damit es im gesamten Projekt verwendet werden kann. Daher müssen wir alle Template-Direktiven {% extend … %} aktualisieren, die davon Gebrauch gemacht haben.

Überprüf den GitHub-Repository um zu sehen, wie die HTML-Vorlagen aussehen müssen.

Hinzufügen von Sitzungssteuerungen

Als nächstes müssen wir die Anmelde- und Abmeldeschaltflächen in unserem Menü bereitstellen. Gehe zu templates/base.html und ändern Sie die <nav> -Element in der Vorlage, das das Navigationsmenü enthält, sodass es wie folgt aussieht.

<nav class="navbar navbar-default">
    <div class="navbar-header">
        <a class="navbar-brand" href="{% url 'reviews:review_list' %}">Winerama</a>
    </div>
    <div id="navbar" class="navbar-collapse collapse">
        <ul class="nav navbar-nav">
            <li><a href="{% url 'reviews:wine_list' %}">Wine list</a></li>
            <li><a href="{% url 'reviews:review_list' %}">Home</a></li>
        </ul>
        <ul class="nav navbar-nav navbar-right">
        {% if user.is_authenticated %}
            <li><a href="{% url 'auth:logout' %}">Logout</a></li>
            {% else %}
            <li><a href="{% url 'auth:login' %}">Login</a></li>
            {% endif %}
        </ul>
    </div>
</nav>

Der wichtige Teil hier ist, wie wir das Kontextobjekt verwenden user.is_authenticated innerhalb eines {% if %} Ausdruck, um die richtigen Menüelemente anzuzeigen. Wenn der Benutzer eingeloggt ist, zeigen wir den Logout-Button und umgekehrt.

Wenn Sie es versucht haben, ist Ihnen wahrscheinlich aufgefallen, dass wir beim Anmelden über das Menü einen 404-Fehler erhalten, wenn wir versuchen, zur Benutzerprofilseite zu navigieren. Das ist gut. Wir haben noch keine Benutzerprofilseite bereitgestellt. Wir werden dieses Problem im nächsten Abschnitt lösen.

Auch dieser Punkt des Projekts entspricht dem Git-Tag stage-1.1.

Benutzerprofilseite

Tatsächlich besteht unser Benutzerprofil aus einer Liste von Bewertungen des eingeloggten Benutzers. Um das zu erreichen, benötigen wir ein paar Dinge:

  • Wir müssen die Standardzuordnung für die Zielseite nach der Anmeldung definieren (wenn a next param ist nicht angegeben).
  • Dann müssen wir eine Zuordnung für die neue Ansicht definieren, die wir hinzufügen werden.
  • Wir müssen eine Ansichtsfunktion definieren, die von einem Benutzer abgegebene Bewertungen zurückgibt.
  • Wir müssen eine Vorlage definieren, um das Ergebnis der vorherigen Ansicht zu rendern.
  • Dazu müssen wir einen Menüpunkt erstellen.

Beginnen wir mit der Definition der Standardzuordnung. Dies erfolgt auf Projektkonfigurationsebene. Gehe zu winerama/settings.py und fügen Sie die folgende Zeile hinzu.

LOGIN_REDIRECT_URL = '/reviews/review/user'

Jetzt müssen wir die Zuordnungen in definieren reviews/urls.py wie gezeigt in das GitHub-Repo auf Stufe 1.2 (Im Moment haben wir Probleme, dieses Code-Snippet inline zu rendern, also müssen Sie es sich dort auf GitHub ansehen).

Dort spezifizieren wir zwei Mappings. Einer wird verwendet, wenn ein Benutzername übergeben wird, und der andere, wenn dies nicht der Fall ist. Die neue Ansicht benötigt eine Funktion in reviews/views.pyNamen user_review_list wie in der URL-Zuordnung definiert. Fügen Sie Ihrer Ansichtsdatei Folgendes hinzu.

def user_review_list(request, username=None):
    if not username:
        username = request.user.username
    latest_review_list = Review.objects.filter(user_name=username).order_by('-pub_date')
    context = {'latest_review_list':latest_review_list, 'username':username}
    return render(request, 'reviews/user_review_list.html', context)

Wie Sie sehen, haben wir dem Code, den wir in der neuesten Bewertungsliste verwendet haben, einfach einen Filter hinzugefügt und dann einen neuen Vorlagennamen verwendet user_review_list.html. Wir hätten die vorhandene Vorlage für verwenden können review_list.html, aber wir möchten den Titel benutzerspezifischer ändern. Schließlich können wir entscheiden, ob Benutzer sich für diese Ansicht anmelden müssen oder nicht. Wenn nicht (wie wir es getan haben), sind Benutzerbewertungen öffentlich, sodass Benutzer, die nicht angemeldet sind, sie auch anzeigen können.

Als nächstes müssen wir die Vorlage wie folgt erstellen.

{% extends 'reviews/review_list.html' %}

{% block title %}
<h2>Reviews by {{ user.username }}</h2>
{% endblock %}

Das heißt, wir verlängern die review_list.html Vorlage und definieren Sie einfach die {% block title %} um den Titel durch den mit dem Benutzernamen zu ersetzen.

Abschließend fügen wir den Menüpunkt für die neue Ansicht hinzu. Wir wollen einen Link, der sagt Hallo USER_NAME neben dem Ausloggen Menüpunkt. Geh und ändere die <nav> Element hinein templates/base.html so sieht es wie folgt aus (siehe GitHub Stage-1.2-Datei wenn Sie Probleme haben, die HTML-Tags unten zu sehen).

<nav class="navbar navbar-default">
    <div class="navbar-header">
        <a class="navbar-brand" href="{% url 'reviews:review_list' %}">Winerama</a>
    </div>
    <div id="navbar" class="navbar-collapse collapse">
        <ul class="nav navbar-nav">
            <li><a href="{% url 'reviews:wine_list' %}">Wine list</a></li>
            <li><a href="{% url 'reviews:review_list' %}">Home</a></li>
        </ul>
        <ul class="nav navbar-nav navbar-right">
        {% if user.is_authenticated %}
            <li><a href="{% url 'reviews:user_review_list' user.username %}">Hello {{ user.username }}</a></li>
            <li><a href="{% url 'auth:logout' %}">Logout</a></li>
            {% else %}
            <li><a href="{% url 'auth:login' %}">Login</a></li>
            {% endif %}
        </ul>
    </div>
</nav>

Center

Schließlich möchten wir in der Lage sein, zu den Bewertungsseiten anderer Benutzer zu navigieren. Wenn wir beispielsweise den Namen eines Benutzers unter einer Weinbewertung sehen, möchten wir in der Lage sein, auf den Namen zu klicken und zu dieser Benutzerbewertungsseite zu gelangen. Dies bedeutet, dass wir aktualisieren müssen review_list.html und review_detail.html Vorlagen und ersetzen Sie den Text des Benutzernamens durch a <a> Element wie folgt (dies ist die reviews_detail.html Schablone).

{% extends 'base.html' %}

{% block title %}
<h2><a href=" url"reviews:wine_detail' review.wine.id %}">{{ review.wine.name }}</a></h2>
{% endblock %}

{% block content %}
<h4>Rated {{ review.rating }} of 5 by <a href=" url"reviews:user_review_list' review.user_name %}" >{{ review.user_name }}</a></h4>
<p>{{ review.pub_date }}</p>
<p>{{ review.comment }}</p>
{% endblock %}

Du kannst zu dem … gehen stage-1.2 um zu sehen, wie diese Dateien nach den Updates aussehen.

Und das ist es. Wir haben eine richtige Benutzer-Landingpage erstellt. Es ist dasselbe wie die Bewertungsliste, aber gefiltert, um nur diese Benutzerbewertungen einzuschließen. Diese Ansicht kann auch verwendet werden, um die Bewertungen eines bestimmten Benutzers zu überprüfen. Dieser Punkt des Projekts entspricht dem Git-Tag stage-1.2.

Registrierungsseite

Wir haben bereits die Möglichkeit, Benutzer zu erstellen, aber nur über die Admin-Oberfläche (oder mithilfe von Code). Wir möchten, dass sich ein nicht registrierter Benutzer anmelden und sein eigenes Benutzerkonto erstellen kann. Wir könnten Formulare und Ansichten erstellen, um dies zu tun, aber es gibt eine sehr schöne Django-Registrierungs-App die wir dafür installieren und verwenden können.

Beginnen wir mit der Installation des Anwendungspakets mit unserem Anaconda-Pip wie folgt. Angenommen, wir befinden uns im Ordner mit der Anaconda-Installation:

./anaconda/bin/pip install django-registration-redux

Wenn alles gut geht, müssen wir die App zum hinzufügen INSTALLED_APPS Liste ein winerama/settings.py folgendermaßen:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'bootstrap3',
    'reviews',
    'registration',
)

Fügen Sie der Einstellungsdatei auch die folgenden Werte hinzu.

ACCOUNT_ACTIVATION_DAYS = 7 
REGISTRATION_AUTO_LOGIN = True 

Sobald wir dies getan haben, müssen wir das vom Standard-Setup verwendete Modell installieren. Führen Sie im Terminal im Projektstamm Folgendes aus.

python manage.py makemigrations

Und dann

pythonmanage.py migrate

Die Anwendung enthält verschiedene Benutzerverwaltungsansichten, aber wir möchten nur die Registrierungsansichten verwenden. Stellen Sie Folgendes ein in der winerama/urls.py Datei.

urlpatterns = [
    url(r'^reviews/', include('reviews.urls', namespace="reviews")),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^accounts/', include('registration.backends.simple.urls')),
    url(r'^accounts/', include('django.contrib.auth.urls', namespace="auth")),    
]

Wir müssen zwei Vorlagen bereitstellen, die die Standardvorlagen ersetzen. Wir möchten, dass unsere besser zum Stil unserer Website passen. Sie sind „templates/registration/registration_form.html“ und „templates/registration/registration_complete.html“. Der erste sieht so aus.

{% extends 'base.html' %}
{% load bootstrap3 %}


{% block title %}
<h2>Register</h2>
{% endblock %}

{% block content %}
<form method="post" class="form">
    {% csrf_token %}
    {% bootstrap_form form layout="inline" %}
    {% buttons %}
    <button type="submit" class="btn btn-primary">
      {% bootstrap_icon "user" %} Register
    </button>
    {% endbuttons %}
</form>
{% endblock %}

Geben Sie hier die Bildbeschreibung ein

Dort folgen wir einfach der gleichen Struktur, die wir für die Anmeldevorlage verwendet haben. Nichts Besonderes. Die für die Registrierung abgeschlossen sieht so aus.

{% extends 'base.html' %}
{% load bootstrap3 %}


{% block title %}
<h2>Register</h2>
{% endblock %}

{% block content %}
Thanks for registering!
{% endblock %}

Geben Sie hier die Bildbeschreibung ein

Sie müssen so benannt werden und sich in der Hauptsache befinden templates/registration Ordner für django-registration um sie zu finden.

Wir haben gerade den einfachsten Ansatz zum Erstellen einer Benutzerregistrierungsfunktion verwendet. Wenn Sie an einem komplexeren (und produktionsbereiten) Ansatz interessiert sind, z. B. das Senden von Aktivierungs-/Bestätigungs-E-Mails an den Benutzer oder Ansichten zum Wiederherstellen/Zurücksetzen von Passwörtern, werfen Sie einen Blick auf die Django-Registrierungsdokumente. Das Hauptproblem bei der Verwendung in diesem Tutorial besteht darin, dass sie die Verwendung eines E-Mail-Servers beinhalten, und das hat nicht viel mit dem zu tun, was wir hier lehren möchten.

Dieser Punkt des Projekts entspricht dem Git-Tag stage-2 des Projektrepos.

Schlussfolgerungen

In diesem Teil des Tutorials haben wir Benutzer und Benutzerverwaltung in unsere Django-App eingeführt. Indem wir von den Benutzern verlangen, dass sie sich registrieren, können wir bessere Benutzerstatistiken sammeln, und dies ist ein grundlegender Schritt beim Aufbau eines benutzerbasierten Empfehlungsprogramms.

Allerdings war unsere Benutzerverwaltung sehr naiv und einfach. Es gibt viele Probleme, die wir angehen müssten, wenn wir dieses System in Produktion nehmen wollen, wie z. B. die Bereitstellung eines zweistufigen Aktivierungsprozesses für Benutzerkonten, die Überprüfung, ob eine E-Mail-Adresse zuvor verwendet wurde, oder sogar die Möglichkeit, dass sich Benutzer mit ihrer anmelden soziale Konten.

Aber was wir bisher getan haben, reicht für unser endgültiges Ziel aus, nämlich zu zeigen, wie eine Website ein Empfehlungssystem enthalten kann und wie ihr Arbeitsablauf beim Sammeln von Benutzerdaten aussieht. Unser oberstes Ziel ist es, Modelle zu erstellen, um Empfehlungen zu geben. Dies wird der Zweck des dritten und letzten Teils unseres Tutorials sein.

Denken Sie daran, dass Sie dem Tutorial in jeder Entwicklungsphase folgen können, indem Sie forken das Repo in Ihr eigenes GitHub-Konto, klonen Sie es dann in Ihren Arbeitsbereich und checken Sie das entsprechende Tag aus. Indem Sie das Repo forken, können Sie es nach Belieben ändern und so viel damit experimentieren, wie Sie möchten. Wenn Sie zu irgendeinem Zeitpunkt ein wenig Hilfe bei einem Schritt des Tutorials benötigen oder es zu Ihrem eigenen machen möchten, können wir eine 1: 1-Codementor-Sitzung darüber abhalten.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *