>백엔드 개발 >파이썬 튜토리얼 >Django 계정 관리 앱(등록 및 활성화

Django 계정 관리 앱(등록 및 활성화

Patricia Arquette
Patricia Arquette원래의
2024-11-04 21:57:021039검색

이 기사에서 무엇을 기대할 수 있습니까?

이전 기사에서 프로젝트 골격 구조를 만들었으며, 이 기사에서는 이를 토대로 작성해 보겠습니다. 덮을 거예요

  • 사용자 및 인증 코드를 포함한 계정 데이터베이스 구조
  • 모델 직렬 변환기.
  • 계정 등록, 활성화를 위한 계정 보기. 다음 기사에서는 로그인, 토큰 새로 고침, 비밀번호 변경, 비밀번호 분실 및 코드 재전송과 같은 나머지 보기를 다룰 것입니다.

지루하지 않게 최대한 많은 세부 사항을 다루도록 노력하겠습니다. 하지만 여전히 Python과 Django의 일부 측면에 익숙하실 것으로 기대합니다.

소스코드의 최종 버전은 https://github.com/saad4software/alive-diary-backend에서 확인하실 수 있습니다

시리즈 순서

관심 있으신 분들은 이전 글을 확인해보세요!

  1. 처음부터 AI 프로젝트, 아이디어, 살아 있는 일기
  2. Google AI Studio로 실현 가능함을 증명하세요
  3. Django API 프로젝트 설정
  4. Django 계정 관리 앱(1), 등록 및 활성화(현재 위치 ?)

계정 앱 설정

앱에서 serializer 파일을 만들어 보겠습니다

from rest_framework import serializers
from app_account.models import *

app_account/serializers.py

및 URL 파일

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/" 접두어를 사용하여 모든 계정 URL을 호출할 수 있습니다.

모델

계정 앱의 주요 모델은 물론 사용자 모델입니다

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 모델을 최대한 단순하게 유지하고 다른 세부 정보를 User와 일대일 관계로 Profile 모델로 옮기는 것이 더 좋지만, 단순화하기 위해 필수 사용자 정보를 추가하겠습니다. 이번에는 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는 관리자(true 값 포함)와 일반 사용자를 구분합니다.

이 프로젝트 사용자를 위해 다음과 같은 여러 필드를 추가했습니다.

  • 관리자 계정과 클라이언트 계정을 구별하기 위해 역할이 2개뿐이므로 이 간단한 프로젝트에는 is_staff를 사용할 수 있지만 대규모 프로젝트에는 역할이 2개 이상 있을 수 있으므로 이 필드는 권한 처리에 필수적입니다.
  • 취미, 직업, 자기소개 사용자에 대해 더 많이 알면 더 나은 성찰을 하는 데 도움이 될 수 있으므로 취미, 직업, 사용자가 자신을 어떻게 설명하는지 질문합니다.
  • 통계를 위한 국가 코드
  • 구독 기반 만료일은 만료_날짜입니다.

계정 활성화, 비밀번호 분실, 코드 재전송을 위한 인증 코드를 보관하고 추적하려면 인증 코드 모델도 필요합니다.

from rest_framework import serializers
from app_account.models import *

app_account/models.py

User 모델과 연결하여 6자리 코드번호의 랜덤값을 생성합니다. 만료 시간도 24시간입니다. 사용자가 여러 이메일 주소의 유효성을 검사하려는 경우를 대비해 이메일도 제출했는데, 이는 드물며 이 앱에서는 삭제할 수 있습니다. 다음은 serializer로 넘어가겠습니다.

등록 API

직렬 변환기부터 시작해 보겠습니다

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

urlpatterns = [

]

app_account/serializers.py

Django 나머지 프레임워크의 ModelSerializer를 사용하고 있습니다. Meta 클래스에서 사용자 모델 get_user_model()과 직렬화된 필드 목록을 선택했습니다.

모델 직렬 변환기에 비밀번호1 및 비밀번호2라는 두 개의 추가 필드를 추가했습니다. 동일한 값을 가지고 있는지 확인하기 위해 유효성 검사 메서드를 덮어썼습니다. 유효한 이메일을 사용자 이름으로 사용하도록 강제하기 위해 사용자 이름 필드에 대한 필드 유효성 검사기를 추가했습니다.
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

개인적으로 저는 정규 표현식을 좋아하지 않고, 이해해 본 적도 없지만 이메일을 확인하는 가장 좋은 방법인 것 같습니다. 더 좋은 방법이 있으면 공유해 주세요.

새 필드인 비밀번호1과 비밀번호2는 원래 사용자 모델에 속하지 않기 때문에 이를 데이터 사전에서 제거하고 직렬 변환기 데이터를 직접 사용하여 새 사용자를 생성하기 위해 비밀번호 필드를 추가했습니다.

Serializer의 모범 사례 딜레마

  • 직렬 변환기는 데이터베이스 쿼리를 사용하고 데이터베이스를 편집해야 합니까?
  • 아니면 기본 필드 유형 확인(문자열, 정수 등)만 수행해야 합니까?

실제로 명확한 답은 없습니다. 예를 들어 Django Rest 프레임워크 모델 직렬 변환기는 고유한 필드에 대한 쿼리를 만드는 것 같습니다. 같은 이름으로 사용을 만들려고 할 때 발생한 직렬 변환기 오류는 직렬 변환기에 의해 생성되었습니다. 전망이 아닙니다.
Create, Save, Update 메소드는 데이터베이스에 값을 씁니다.
하지만 뷰에서만 데이터베이스에 액세스하는 것이 관심의 분리유연성

에 더 부합하는 것 같습니다.

어떤 것이 더 좋다고 생각하시나요?

데이터베이스 업데이트 방법과 데이터베이스 쿼리를 분리하는 등 사물을 분리하는 방법에 대해 많이 읽었습니다. 그럼 그렇게 해보자. views.py 파일에서 AccountActivateView를 생성하는 방법은 다음과 같습니다.

우리의 경우 새로운 사용자 및 유효성 검사 코드 인스턴스를 생성하고 직렬 변환기에서 확인 코드를 보내기 위해 RegisterSerializer의 생성 메서드를 덮어쓸 수 있습니다.

그 대신 모델 관련 작업은 뷰 파일에 보관하겠습니다

등록 화면으로 이동

from rest_framework import serializers
from app_account.models import *

app_account/views.py

나머지 프레임워크의 CreatAPIView를 사용하고 있으며, serializer_class 스키마로 POST 요청을 받아들이고, BrowsableAPIRenderer는 이 API에 대한 웹 인터페이스를 구축하며, 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를 상속받아 렌더 메소드를 덮어썼습니다. 직렬 변환기 오류.

  • 응답 상태 코드를 읽고 코드 필드에 넣는 것으로 시작했습니다
  • 실제 응답 데이터를 응답 스키마의 데이터 필드로 옮겼습니다
  • 성공적인 응답과 오류를 구별하기 위해 상태 코드를 확인합니다. 상태 코드가 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.