이제 로그인 폼과 화면에 대한 접근권한을 설정하는 법에 대해 알아보도록 하겠습니다.
/fastcampus/user/urls.py
from django.urls import path
from user import views
urlpatterns = [
path('user/', views.user, name="user"),
path('login/', views.login, name="login"),
]
/fastcampus/user/views.py
from django.utils import timezone
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from user.serializers import UserSerailizer
from user.models import User
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
# Shop객체들을 다 serialize한 결과를 json으로 parsing해서 json형태로 이를 반응하겠다
@csrf_exempt
def user(request):
if request.method == 'GET':
shop = User.objects.all()
return render(request, 'user/user_list.html', {'user_list': shop})
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = UserSerailizer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
@csrf_exempt
def login(request):
if request.method == 'POST':
name = request.POST['name']
try:
request.session['user_id'] = User.objects.all().get(user_name=name).id
print(request.session['user_id'])
return render(request, 'user/success.html')
except:
return render(request, 'user/fail.html')
elif request.method == 'GET':
return render(request, 'user/login.html')
구현한건 login함수입니다. get요청을 하면 간단히 login템플릿을 보여줍니다.
/fastcampus/user/templates/user/login.html
<form method="post" action="{% url 'login' %}">
<ol>
<h4>가입하신 이름을 입력해주세요.</h4>
<input type="text" name="name" required>
</ol>
<input type="submit" value="로그인하기">
</form>
이제 로그인 폼에서 name값을 입력받게 되어 있습니다. 그러면 이 request.POST['name']으로 이름을 받습니다. 그리고 해당 user_name을 가진 User의 id를 session에 집어 넣습니다. 그리고 로그인에 성공하면 success.html으로 가게 합니다. 만약 로그인 되지 않았다. 즉 회원 디비에 해당 이름이 없다면 fail.html로 가게 했습니다. 간단히 보여드리겠습니다.
현서는 제가 이미 가장 맨 첫번째로 만든 유저입니다. 이를 통해 로그인하면 로그인에 성공하였다고 뜨고, id를 출력한 값은 1이 잘 뜨는 것을 보실 수 있습니다. 만약에 유저네임이 없다면?
다음과 같이 실패했다고 뜹니다.
여기서 이제 접근권한에 대한 설정을 진행해 보도록 하겠습니다. /order/shops/는 가게목록을 보여주는 화면입니다. 저는 이 창을 사용자만 볼 수 있게 하고 싶습니다. 이를 위해서 아래와 같은 코드를 짰습니다.
/fastcampus/order/views.py
from django.utils import timezone
from django.shortcuts import render
from order.models import Shop, Menu, Order, Orderfood
from user.models import User
from order.serializer import ShopSerializer, MenuSerializer
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
# Shop객체들을 다 serialize한 결과를 json으로 parsing해서 json형태로 이를 반응하겠다
@csrf_exempt
def shop(request):
if request.method == 'GET':
# shop = Shop.objects.all()
# serializer = ShopSerializer(shop, many=True)
# return JsonResponse(serializer.data, safe=False)
try:
if User.objects.all().get(id=request.session['user_id']).user_type == 0:
shop = Shop.objects.all()
return render(request, 'order/shop_list.html', {'shop_list': shop})
else:
return render(request, "order/fail.html")
except:
return render(request, "order/fail.html")
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = ShopSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
@csrf_exempt
def menu(request, shop):
if request.method == 'GET':
# get으로 하게 되면 menu1개 밖에 불러오지 못하게 된다.
# 모든 menu를 불러오고 싶을 떄는 배열로서 filter를 사용해 주면 된다.
menu = Menu.objects.filter(shop=shop)
# many=True는 값이 여러개여도 상관하지 않겠다는 의미이다.
# serializer = MenuSerializer(menu, many=True)
# return JsonResponse(serializer.data, safe=False)
return render(request, 'order/menu_list.html', {'menu_list': menu, 'shop': shop})
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = MenuSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
@csrf_exempt
def order(request):
if request.method == 'POST':
address = request.POST['address']
shop = request.POST['shop']
food_list = request.POST.getlist('menu')
order_date = timezone.now()
shop_item = Shop.objects.get(pk=int(shop))
shop_item.order_set.create(
order_date=order_date, address=address, shop=int(shop))
shop_item.save()
order_item = Order.objects.get(
pk=int(shop_item.order_set.latest('id').id))
for food in food_list:
order_item.orderfood_set.create(food_name=food)
return render(request, 'order/success.html')
elif request.method == 'GET':
order_list = Order.objects.all()
return render(request, 'order/order_list.html', {'order_list': order_list})
shops함수를 조금 수정해 주었습니다. 일단 첫번째 try에서 request.session['user_id']가 아예 없는 경우, 즉 로그인하지 않은 경우를 막은 것입니다. 로그인되어 있다는 가정하에 id가 request.session['user_id']와 겹치는 유저를 찾고 이의 user_type이 0이라면 사용자이고 그 외에는 사장 아니면 배달기사가 됩니다. 즉 0인 경우만 shops목록을 보여주면 됩니다.
저는 현서가 그냥 사용자라고 했으니까 이에대해 잘 목록이 뜨는지 확인하겠습니다.
다음과 같이 잘 확인되지만, 제가 만약에 현서 사장 ( user_type == 2 )로 들어가면 접근권한이 없다고 떠야 할겁니다. 확인해 보겠습니다.
정상 작동합니다. 그리고 로그인 되어 있지 않은 경우도 확인하면 아마 접근권한이 없다고 위와 똑같이 뜰겁니다.
다음에는 이제 중규모 아키텍쳐를 위한 도커에 대해 알아보겠습니다.