Django 帳戶管理應用程式(註冊和激活

Patricia Arquette
發布: 2024-11-04 21:57:02
原創
960 人瀏覽過

從這篇文章可以期待什麼?

我們在上一篇文章中已經建立了專案的骨架結構,本文將在此基礎上進行建構。它將覆蓋

  • 帳戶資料庫結構,包括使用者和驗證碼。
  • 模型序列化器。
  • 帳號註冊、啟動的帳號檢視。下一篇文章應該涵蓋其餘的視圖,例如登入、刷新令牌、更改密碼、忘記密碼和重新發送程式碼。

我會盡力介紹盡可能多的細節,以免讓您感到無聊,但我仍然希望您熟悉 Python 和 Django 的某些方面。

最終版本的原始碼可以在 https://github.com/saad4software/alive-diary-backend

系列訂購

有興趣可以查看之前的文章!

  1. 從頭開始的人工智慧專案、創意、Alive 日記
  2. 用 Google AI Studio 證明它是可行的
  3. Django API 專案設定
  4. Django 帳戶管理應用程式(一)、註冊和啟動(你在這裡?)

帳戶應用程式設定

讓我們在應用程式中建立序列化器檔案

from rest_framework import serializers
from app_account.models import *
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

app_account/serializers.py

和網址文件

from django.urls import path, include
from .views import *

urlpatterns = [

]
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

app_account/urls.py

最後,讓我們透過將專案 url 檔案編輯為
將應用程式 url 連接到專案 url

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

現在我們可以呼叫任何前綴為「api/account/」的帳戶網址

模特兒

帳戶應用程式的主要模型當然是使用者模型

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

通常,最好保持用戶模型盡可能簡單,並將其他詳細資訊移動到與用戶具有一對一關係的配置文件模型中,但為了簡化事情,我將添加所需的用戶資訊這次直接進入User 模型。

我們繼承AbstractUser模型,AbstractUser包含多個欄位

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(...)

登入後複製
登入後複製

最重要的是:

  • 用戶名將用於登入。
  • is_active 將用於防止未經驗證的帳號登入。
  • is_staff 將區分 admin(值為 true)和普通用戶。

我們還為此專案使用者添加了多個字段,它們是

  • 為了區分管理員和客戶帳戶,我們可以在這個簡單的專案中使用 is_staff,因為我們只有兩個角色,但較大的專案可以有兩個以上的角色,使得該欄位對於權限處理至關重要。
  • 嗜好、工作、個人簡介 更了解使用者有助於建立更好的反思,因此我們詢問使用者的愛好、工作以及如何描述自己。
  • 用於統計的國家代碼
  • Expiration_date 表示基於訂閱的到期日期。

我們還需要一個驗證碼模型來保存和追蹤帳戶啟動、忘記密碼和重新發送驗證碼的驗證碼。

from rest_framework import serializers
from app_account.models import *
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

app_account/models.py

它與 User 模型連接並產生 6 位元程式碼的隨機值。它還有 24 小時的過期時間。我們還歸檔了電子郵件,以防用戶想要驗證多個電子郵件地址,這種情況很少見,可以為此應用程式刪除。接下來讓我們轉向序列化器。

註冊API

讓我們從序列化器開始

from django.urls import path, include
from .views import *

urlpatterns = [

]
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

app_account/serializers.py

我們正在使用來自 Django Rest 框架的 ModelSerializer。我們在 Meta 類別中選擇了使用者模型 get_user_model() 和序列化欄位清單。

我們在模型序列化器中加入了兩個附加欄位:password1 和password2。為了驗證它們具有相同的值,我們重寫了 validate 方法。為了強制使用有效的電子郵件作為使用者名,我們為使用者名字段添加了一個欄位驗證器。
is_valid_email 函數應該看起來像這樣

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

就我個人而言,我不喜歡正規表示式,我從來沒有掌握它們,但它們似乎是驗證電子郵件的最佳方式。如果您有更好的方法,請與我們分享。

由於我們的新字段password1和password2不屬於原始使用者模型,因此我們將它們從資料字典中刪除並新增了password字段,以便直接使用序列化器資料來建立新使用者。

序列化器的最佳實踐困境

  • 序列化器應該使用資料庫查詢和編輯資料庫嗎?
  • 或者他們應該只進行基本欄位類型驗證(字串、整數…)?

實際上沒有明確的答案,例如,Django Rest框架模型序列化器似乎對唯一字段進行查詢,就像我們在嘗試創建同名用途時遇到的序列化器錯誤,它是由序列化器生成的,不是風景。
建立、儲存、更新方法將值寫入資料庫。
然而,僅在視圖中存取資料庫似乎更符合關注點分離靈活性

你覺得哪個比較好?

我讀過很多關於將事物分開的內容,甚至將資料庫查詢與資料庫更新方法分開。所以讓我們嘗試這樣做。在views.py 檔案中建立AccountActivateView 應該如下所示。

在我們的例子中,我們可以覆寫 RegisterSerializer 的建立方法,以便建立新使用者和驗證程式碼實例,甚至從序列化器發送驗證程式碼。

但是,我會將模型相關操作保留在視圖檔案中

讓我們轉到註冊視圖

from rest_framework import serializers
from app_account.models import *
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

app_account/views.py

我們使用其餘框架中的CreatAPIView,它接受具有serializer_class schema的POST請求,BrowsableAPIRenderer為此API建立一個Web介面,JSONRenderer負責建構JSON回應。

重寫perform_create方法允許我們控制使用者建立機制,我們正在建立使用者實例,確保is_active欄位設定為False,然後建立連接到新使用者模型的驗證碼實例,最後發送向使用者發送包含驗證碼的電子郵件。

發送電子郵件需要在設定文件中正確配置電子郵件字段,如果您在這一點上遇到問題,請告訴我,以便為此創建單獨的文章

最後,讓我們加入 API url

from django.urls import path, include
from .views import *

urlpatterns = [

]
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

app_account/urls.py

好啊,我們來試試看

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/account/', include('app_account.urls')),

]
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

打開http://localhost:8555/api/account/register,我們應該可以看到這樣的內容(這是由於BrowsableAPIRenderer)

Django accounts management app ( registration and activation

必填欄位為使用者名稱、密碼1和密碼2,我們希望使用電子郵件作為使用者名稱。
看起來不錯,它創建了一個使用者模型,並連接了驗證碼模型(使用SqlBrowser開啟SQLite db檔案)。但預設響應看起來像這樣,狀態為 201。

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))
登入後複製
登入後複製

我希望所有回應都具有此架構

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(...)

登入後複製
登入後複製
  • 狀態應該是「成功」或「錯誤」
  • code 是回應狀態代碼
  • data 是實際的回應資料
  • 訊息應包含錯誤文字或任何其他訊息

但是該怎麼做呢?
最好的方法是實作自訂 JSON 渲染器 函數。讓我們開始吧

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

我們繼承自JSONRenderer並覆寫了render方法。序列化器錯誤。

  • 先讀取回應狀態碼,並將其放入程式碼欄位
  • 我們將實際回應資料移到回應架構中的資料欄位
  • 為了區分錯誤和成功回應,我們檢查狀態碼。如果狀態碼在 200 系列中,表示成功回應
  • 如果不是,那就是一個錯誤。因此我們將狀態更改為“錯誤”,並從回應詳細資料欄位中提取錯誤訊息(如果可用)。
  • 序列化器的驗證錯誤沒有詳細資訊字段,它是一個字典,指示每個字段名稱(鍵)的錯誤訊息(值),因此我們創建了一個小函數 dict2string 將其轉換為簡單字串。我覺得還可以進一步改進,你能幫忙嗎?

這就是反應模式,讓我們現在嘗試使用它!
在views.py中將我們的自訂渲染器新增至註冊視圖類別

from rest_framework import serializers
from app_account.models import *
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

app_account/views.py

運行伺服器,開啟http://localhost:8555/api/account/register/ 直接看到差異

Django accounts management app ( registration and activation

我們可以在錯誤訊息中看到我們的架構? ,酷,讓我們嘗試註冊一個新用戶,我將其稱為“test5@gmail.com”

Django accounts management app ( registration and activation

看起來很棒,現在讓我們測試序列化器驗證錯誤,我們將嘗試再次註冊同一用戶

Django accounts management app ( registration and activation

太棒了,這是一個驗證錯誤回應,它被序列化為欄位:訊息
註冊後會發生什麼事?這是驗證
註冊->確認電子郵件->登入->無論如何

啟動API

我們要檢查用戶是否收到了我們在註冊時發送的激活碼,如果用戶發送了正確的代碼,我們將激活他們的帳戶,如果沒有,我們將要求他們再次檢查,或者也許重新發送代碼(稍後再使用另一個API)
與註冊 API 建立流程類似,讓我們從序列化器開始

from django.urls import path, include
from .views import *

urlpatterns = [

]
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

這與某個資料庫模型無關,所以我們繼承自通用序列化器,注意序列化器與表單類似,所以我們設定欄位及其驗證規則。
我們使用兩個字串欄位(CharField),兩者都是必需的,使用者名稱(使用者電子郵件地址)和程式碼。

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

由於我們使用的是自訂API視圖,因此我們繼承自APIView,它提供了5個功能(get、post、put、delete和patch)。我們從 POST 請求中反序列化請求數據,並驗證其類型,然後進行查詢以查找提供的數據是否存在,如果存在,我們會啟動用戶並從其表中刪除代碼物件。如果不是,我們會發送錯誤訊息,指出它是「invalid_code」。最後,應該更新 URL 檔案以包含此視圖的 URL

from rest_framework import serializers
from app_account.models import *
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

app_account/urls.py

現在我們可以開啟URL http://localhost:8555/api/account/activate/,我們使用的是自訂API視圖,所以它沒有取得必填欄位

Django accounts management app ( registration and activation

我們可以從資料庫中取得程式碼(用於測試目的)。該請求應類似於

from django.urls import path, include
from .views import *

urlpatterns = [

]
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

如果一切順利,回應應該如下圖

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/account/', include('app_account.urls')),

]
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

就是這樣
讓我們總結一下吧!我知道我們還沒有登錄,但這確實是一篇很長的文章,我們下一篇繼續

敬請期待?

以上是Django 帳戶管理應用程式(註冊和激活的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!