로그인&회원가입 정도만 지원하는 초미니 인스타그램을 구동할 수 있는 API 시스템을 만들어보자!
$ git checkout main # 브랜치 생성은 꼭 main 에서
$ git branch feature/signup
#views.py
# views.py
import json
from django.http import JsonResponse
from django.views import View
from users.models import User
class UsersView(View):
def post(self, request):
data = json.loads(request.body)
username = data['username']
first_name = data['first_name']
last_name = data['last_name']
email = data['email']
password = data['password']
phone_number = data['phone_number']
User.objects.create(
username = username,
first_name = first_name,
last_name = last_name,
email = email,
password = password,
phone_number = phone_number,
)
return JsonResponse({'messasge':'SUCCESS'}, status=201)
views.py
에 임포트한 모듈을 작성할 때에는 내장 모듈 > 내가 pip한 모듈 > 내가 만든 모듈
순으로 쓰는게 컨벤션이다.{"message": "SUCCESS"}, status code 201
반환.#views.py
import json #프론트로부터 받은 json을 백에서 사용할 수 있는 형태로 바꿈
import re #re 모듈의 match() 함수는 문자열 패턴이 일치하는지 확인
from django.http import JsonResponse #django가 dict를 json으로 변환한다.
from django.views import View #view기능을 사용할 수 있게 한다.
from django.core.exceptions import ValidationError #유효성검사를 통과하지 못하면 오류를 발생시키는 모듈
from users.models import User #User class
from users.validation import validate_username, validate_email, validate_password, validate_phonenumber, validate_lastname, validate_firstname
class SignUpView(View):
def post(self, request):
try:
data = json.loads(request.body)
username = data['username']
first_name = data['first_name']
last_name = data['last_name']
email = data['email']
password = data['password']
phone_number = data['phone_number']
if User.objects.filter(email=email).exists():
return JsonResponse({'message':'DUPLICATED_EMAIL'}, status=400)
#서로 다른 사람이 같은 이메일 사용 불가
validate_username(username) #validation.py 참조
validate_email(email)
validate_password(password)
validate_phonenumber(phone_number)
validate_lastname(last_name)
validate_firstname(first_name)
User.objects.create( #db 테이블에 넣을 데이터 생성
username = username,
first_name = first_name,
last_name = last_name,
email = email,
password = password,
phone_number = phone_number,
)
return JsonResponse({'message':'SUCCESS'}, status=201)
#데이터 생성 성공시 SUCCESS 반환.
except KeyError:
return JsonResponse({'message':'KEY_ERROR'}, status=400)
#없는 KEY값을 넣은 경우 KEY_ERROR 반환
except ValidationError as error:
return JsonResponse({"message": error.message}, status=400)
#validation error가 발생할 경우 validation.py에 작성한 error message 호출
#validatiton.py
import re
from django.http import JsonResponse
from django.core.exceptions import ValidationError
USERNAME_REGEX = '^([A-Za-z0-9가-힣]{2,})+'
EMAIL_REGEX = '^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$'
PASSWORD_REGEX = '^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$'
PHONE_NUMBER_REGEX = '^01([0|1|6|7|8|9]?)-?([0-9]{3,4})-?([0-9]{4})$'
LAST_NAME_REGEX = '^[a-zA-Z가-힣]+$'
FIRST_NAME_REGEX = '^[a-zA-Z가-힣]+$'
def validate_username(value):
if not re.match(USERNAME_REGEX,value):
raise ValidationError('INVALID_USERNAME')
def validate_email(value):
if not re.match(EMAIL_REGEX,value):
raise ValidationError('INVALID_EMAIL')
def validate_password(value):
if not re.match(PASSWORD_REGEX,value):
raise ValidationError('INVALID_PASSWORD')
def validate_phonenumber(value):
if not re.match(PHONE_NUMBER_REGEX,value):
raise ValidationError('INVALID_PHONE_NUMBER')
def validate_lastname(value):
if not re.match(LAST_NAME_REGEX,value):
raise ValidationError('INVALID_LAST_NAME')
def validate_firstname(value):
if not re.match(FIRST_NAME_REGEX,value):
raise ValidationError('INVALID_LAST_NAME')
#settings.py에 앱 이름 추가
INSTALLED_APPS = [
...
'users',
]
#users/apps.py
from django.urls import path
from users.views import SignUpView, SignInView
urlpatterns = [
path('/signup', SignUpView.as_view()),
]
url.py
에 127.0.0.1:8000/users
경로를 설정해 놨으니 127.0.0.1:8000/signup
으로 POST를 보내면 되겠다.#httpie설치
#Ubuntu
sudo apt install httpie
#Mac
brew install httpie
$ python manage.py runserver
http -v POST 127.0.0.1:8000/users/signup username='귀여운철수' first_name='철수' last_name='김' email='cheolsu@gmail.com' password='cuty0110!!' phone_number='010-1010-0101'