Wir haben im vorherigen Artikel die Grundstruktur des Projekts erstellt, dieser Artikel wird darauf aufbauen. es wird abdecken
Ich werde versuchen, so viele Details wie möglich abzudecken, ohne Sie zu langweilen, erwarte aber dennoch, dass Sie mit einigen Aspekten von Python und Django vertraut sind.
Die endgültige Version des Quellcodes finden Sie auf https://github.com/saad4software/alive-diary-backend
Schauen Sie sich bei Interesse frühere Artikel an!
Lassen Sie uns eine Serialisierungsdatei in der App erstellen
from rest_framework import serializers from app_account.models import *
app_account/serializers.py
und die URL-Datei
from django.urls import path, include from .views import * urlpatterns = [ ]
app_account/urls.py
Abschließend verbinden wir die App-URLs mit den Projekt-URLs, indem wir die Projekt-URL-Datei bearbeiten als
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/account/', include('app_account.urls')), ]
alive_diary/urls.py
Jetzt können wir jede Konto-URL mit dem Präfix „api/account/“ aufrufen
Das Hauptmodell für die Konten-App ist natürlich das Benutzermodell
from django.db import models from django.contrib.auth.models import AbstractUser from datetime import timedelta, datetime class User(AbstractUser): userTypes = ( ('A', 'Admin'), ('C', 'Client'), ) role = models.CharField(max_length=1, choices=userTypes, default="C") hobbies = models.CharField(max_length=255, null=True, blank=True) job = models.CharField(max_length=100, null=True, blank=True) bio = models.TextField(null=True, blank=True) country_code = models.CharField(max_length=10, null=True, blank=True) expiration_date = models.DateTimeField(default=datetime.now()+timedelta(days=30))
app_account/models.py
Normalerweise ist es besser, das Benutzermodell so einfach wie möglich zu halten und andere Details in ein Profilmodell mit einer Eins-zu-eins-Beziehung zum Benutzer zu verschieben, aber um die Dinge zu vereinfachen, füge ich die erforderlichen Benutzerinformationen hinzu Diesmal direkt zum Benutzermodell.
Wir erben vom AbstractUser-Modell, AbstractUser enthält mehrere Felder
class AbstractUser(AbstractBaseUser, PermissionsMixin): username = models.CharField(...) first_name = models.CharField(...) last_name = models.CharField(...) email = models.EmailField(...) is_staff = models.BooleanField(...) is_active = models.BooleanField(...), date_joined = models.DateTimeField(...)
Die wichtigsten sind:
Wir haben außerdem mehrere Felder für diesen Projektbenutzer hinzugefügt:
Wir benötigen außerdem ein Bestätigungscode-Modell, um Bestätigungscodes für die Kontoaktivierung, das Vergessen von Passwörtern und das erneute Senden von Codes aufzubewahren und zu verfolgen.
from rest_framework import serializers from app_account.models import *
app_account/models.py
Es verbindet sich mit dem Benutzermodell und generiert einen Zufallswert einer 6-stelligen Codenummer. es hat auch eine Ablaufzeit von 24 Stunden. Für den Fall, dass der Benutzer mehrere E-Mail-Adressen validieren möchte, haben wir auch E-Mail-Adressen archiviert. Dies ist selten und kann für diese App entfernt werden. Kommen wir als nächstes zu den Serialisierern.
Beginnen wir mit dem Serialisierer
from django.urls import path, include from .views import * urlpatterns = [ ]
app_account/serializers.py
Wir verwenden ModelSerializer vom Django-Rest-Framework. Wir haben das Benutzermodell get_user_model() in der Klasse Meta und eine Liste serialisierter Felder ausgewählt.
Wir haben dem Modellserialisierer zwei zusätzliche Felder hinzugefügt: Passwort1 und Passwort2. Um zu überprüfen, ob sie denselben Wert haben, haben wir die Methode „validate“ überschrieben. Und um die Verwendung einer gültigen E-Mail-Adresse als Benutzernamen zu erzwingen, haben wir einen Feldvalidator für das Feld „Benutzername“ hinzugefügt.
Die Funktion is_valid_email sollte ungefähr so aussehen
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/account/', include('app_account.urls')), ]
common/utils.py
Ich persönlich mag reguläre Ausdrücke nicht, ich verstehe sie nie, aber sie scheinen die beste Möglichkeit zu sein, E-Mails zu validieren. Wenn Sie einen besseren Weg haben, teilen Sie ihn uns bitte mit.
Da unsere neuen Felder „Passwort1“ und „Passwort2“ nicht zum ursprünglichen Benutzermodell gehören, haben wir sie aus dem Datenwörterbuch entfernt und das Passwortfeld hinzugefügt, um Serialisierungsdaten direkt zum Erstellen eines neuen Benutzers zu verwenden.
Es gibt eigentlich keine eindeutige Antwort, zum Beispiel scheinen Serialisierer des Django Rest-Framework-Modells Abfragen nach eindeutigen Feldern durchzuführen, wie der Serializer-Fehler, den wir bekamen, als wir versuchten, eine Verwendung mit demselben Namen zu erstellen, er wurde vom Serializer generiert, nicht die Aussicht.
Die Methoden „Create“, „Save“, „Update“ schreiben Werte in die Datenbank.
Der Zugriff auf die Datenbank nur in Ansichten scheint jedoch eher mit Bedenkenstrennung und Flexibilität in Einklang zu stehen.
Was ist Ihrer Meinung nach besser?
Ich habe viel über die Trennung von Dingen gelesen, sogar über die Trennung von Datenbankabfragen und Datenbankaktualisierungsmethoden. Also lasst uns das versuchen. Das Erstellen der AccountActivateView in der Datei „views.py“ sollte so aussehen.
In unserem Fall können wir die Erstellungsmethode für RegisterSerializer überschreiben, um sofort einen neuen Benutzer und Validierungscode zu erstellen und sogar den Bestätigungscode vom Serializer zu senden.
Aber stattdessen behalte ich die modellbezogenen Vorgänge in der Ansichtsdatei
Gehen wir zur Registrierungsansicht
from rest_framework import serializers from app_account.models import *
app_account/views.py
Wir verwenden CreatAPIView aus dem Rest-Framework, es akzeptiert POST-Anfragen mit dem Schema von serializer_class, der BrowsableAPIRenderer erstellt eine Webschnittstelle für diese API und der JSONRenderer ist für die Erstellung der JSON-Antwort verantwortlich.
Das Überschreiben der perform_create-Methode ermöglicht uns die Steuerung des Benutzererstellungsmechanismus. Wir erstellen den Benutzer-Instant, stellen sicher, dass das Feld is_active auf False gesetzt ist, erstellen dann den Verifizierungscode-Instant, der mit dem neuen Benutzermodell verbunden ist, und senden ihn schließlich eine E-Mail mit dem Bestätigungscode an den Benutzer.
Für das Versenden der E-Mail ist die korrekte Konfiguration der E-Mail-Felder in der Einstellungsdatei erforderlich. Bitte lassen Sie mich wissen, wenn Sie in diesem speziellen Punkt Probleme haben, um einen separaten Artikel dafür zu erstellen
Zuletzt fügen wir noch die API-URL hinzu
from django.urls import path, include from .views import * urlpatterns = [ ]
app_account/urls.py
Schön, probieren wir es mal aus
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/account/', include('app_account.urls')), ]
Wenn wir http://localhost:8555/api/account/register öffnen, sollten wir so etwas sehen können (es liegt am BrowsableAPIRenderer)
Die erforderlichen Felder sind Benutzername, Passwort1 und Passwort2. Wir gehen davon aus, dass die E-Mail-Adresse als Benutzername verwendet wird.
Es sieht in Ordnung aus, es hat ein Benutzermodell mit einem damit verbundenen Bestätigungscodemodell erstellt (habe SqlBrowser zum Öffnen der SQLite-DB-Datei verwendet). Aber die Standardantwort sieht mit dem Status 201 so aus.
from django.db import models from django.contrib.auth.models import AbstractUser from datetime import timedelta, datetime class User(AbstractUser): userTypes = ( ('A', 'Admin'), ('C', 'Client'), ) role = models.CharField(max_length=1, choices=userTypes, default="C") hobbies = models.CharField(max_length=255, null=True, blank=True) job = models.CharField(max_length=100, null=True, blank=True) bio = models.TextField(null=True, blank=True) country_code = models.CharField(max_length=10, null=True, blank=True) expiration_date = models.DateTimeField(default=datetime.now()+timedelta(days=30))
Ich bevorzuge, dass alle Antworten dieses Schema haben
class AbstractUser(AbstractBaseUser, PermissionsMixin): username = models.CharField(...) first_name = models.CharField(...) last_name = models.CharField(...) email = models.EmailField(...) is_staff = models.BooleanField(...) is_active = models.BooleanField(...), date_joined = models.DateTimeField(...)
Aber wie geht das?
Der beste Weg ist die Implementierung einer benutzerdefinierten JSON-Renderer-Funktion. Lass es uns tun
import random class VerificationCode(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) code = models.CharField(max_length=6, default=random.randint(111111, 999999)) email = models.EmailField() expiration_date = models.DateTimeField(default=datetime.now()+timedelta(days=1)) def __str__(self): return self.user.username
common/utils.py
Wir haben von JSONRenderer geerbt und die Render-Methode überschrieben. Serialisierungsfehler.
Das war's mit dem Antwortschema. Probieren wir es jetzt aus!
Fügen Sie in „views.py“ unseren benutzerdefinierten Renderer zur Registeransichtsklasse hinzu
from rest_framework import serializers from app_account.models import *
app_account/views.py
Wenn Sie den Server ausführen und http://localhost:8555/api/account/register/ öffnen, wird der Unterschied direkt angezeigt
Wir können unser Schema in der Fehlermeldung sehen? Cool, versuchen wir, einen neuen Benutzer zu registrieren. Ich nenne ihn „test5@gmail.com“
Sieht großartig aus. Jetzt testen wir den Validierungsfehler des Serialisierers. Wir werden versuchen, denselben Benutzer erneut zu registrieren
Wunderbar, das ist eine Validierungsfehlerantwort, sie wurde als field:message
serialisiert
Was kommt nach der Registrierung? es ist eine Bestätigung
registrieren -> E-Mail bestätigen -> Anmelden -> was auch immer
Wir möchten überprüfen, ob der Benutzer den Aktivierungscode erhalten hat, den wir bei der Registrierung gesendet haben oder nicht. Wenn der Benutzer den richtigen Code sendet, aktivieren wir sein Konto. Wenn nicht, werden wir ihn bitten, erneut nachzuschauen, oder vielleicht Senden Sie den Code erneut (eine andere API für später)
Beginnen wir ähnlich wie beim Erstellungsprozess der Registrierungs-API mit dem Serialisierer
from django.urls import path, include from .views import * urlpatterns = [ ]
Dies hängt nicht mit einem bestimmten Datenbankmodell zusammen, daher erben wir vom generischen Serializer. Beachten Sie, dass Serializer Formularen ähneln, daher legen wir die Felder und ihre Validierungsregeln fest.
Wir verwenden zwei Zeichenfolgenfelder (CharField), beide sind erforderlich, Benutzername, der die E-Mail-Adresse des Benutzers ist, und Code.
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/account/', include('app_account.urls')), ]
app_account/views.py
Da wir eine benutzerdefinierte API-Ansicht verwenden, die wir von APIView erben, bietet sie 5 Funktionen (Abrufen, Posten, Einfügen, Löschen und Patchen). Wir deserialisieren Anforderungsdaten von POST-Anfragen und validieren ihren Typ. Anschließend führen wir eine Abfrage durch, um herauszufinden, ob die bereitgestellten Daten vorhanden sind oder nicht. Wenn sie vorhanden sind, aktivieren wir den Benutzer und entfernen das Codeobjekt aus seiner Tabelle. Wenn nicht, senden wir eine Fehlermeldung, dass es sich um einen „invalid_code“ handelt. Schließlich sollte die URL-Datei aktualisiert werden, um die URL dieser Ansicht einzuschließen
from rest_framework import serializers from app_account.models import *
app_account/urls.py
Jetzt können wir die URL http://localhost:8555/api/account/activate/ öffnen. Wir verwenden eine benutzerdefinierte API-Ansicht, sodass das erforderliche Feld nicht angezeigt wird
Wir können den Code aus der Datenbank abrufen (zu Testzwecken). Die Anfrage sollte wie folgt aussehen:
from django.urls import path, include from .views import * urlpatterns = [ ]
Wenn alles erfolgreich verlaufen ist, sollte die Antwort wie folgt aussehen:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/account/', include('app_account.urls')), ]
Das ist es
Bringen wir es zum Abschluss! Ich weiß, dass wir uns noch nicht eingeloggt haben, aber es ist tatsächlich ein sehr langer Artikel geworden, lasst uns im nächsten Artikel fortfahren
Bleiben Sie dran ?
Das obige ist der detaillierte Inhalt vonDjango-Kontoverwaltungs-App (Registrierung und Aktivierung).. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!