본문 바로가기
  • 소소한 개발자 이야기
Python & Django/Django Framework 실전

[Decorator] - 페이지 권한 쉽게 설정하기

by Siwan_Min 2020. 8. 16.
728x90

Decorator란?

1) 함수를 Wrapping

2) 기능의 재사용

을 말합니다. 

 

함수에 

이런 기능을 추가하고 싶을 때 추가하고자 하는 함수가 1~2개라면 그냥 추가해주셔도 크게 문제가 되지 않습니다. 

 

하지만 이런 기능을 추가해야되는 함수가 100개라면 어떻게 될까요?? 뭐 근성이 좋으시면 복붙하셔도 좋고 직접 타이핑 하셔도 좋습니다. 그럼 그렇게 힘들게 100개를 타이핑 했다고 칩시다. 

 

근데 만약에 저 코드를 수정해야 된다면 어떡할까요?? 100개를 다시 다 고쳐야겠죠....

 

이런것을 방지하기 위한 그냥이 바로 Decorator 입니다. 

이러한 함수를 만들어 놓고 

 

내가 사용하고자 하는 함수 위에다가 

 

이런 식으로 해 놓으면 함수가 Decorator 위에서 사용이 되는겁니다. 이렇게 하면 재사용이나 수정 등이 용이하겠죠??? 

이것이 바로 Decorator 입니다. 

 


Decorator 생성하기 

fcuser 앱에서 decorators.py를 생성해줍니다.

decorators.py

소스 코드를 아래와 같이 작성해주세요.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from django.shortcuts import redirect
from .models import Fcuser
 
 
def login_required(function):
    def wrap(request, *args, **kwargs):
        user = request.session.get('user')
        if user is None or not user:
            return redirect('/login')
        return function(request, *args, **kwargs)
 
    return wrap
 
def admin_required(function):
    def wrap(request, *args, **kwargs):
        user = request.session.get('user')
        if user is None or not user:
            return redirect('/login')
 
        user = Fcuser.objects.get(email=user)
        if user.level != 'admin':
            return redirect('/')
 
        return function(request, *args, **kwargs)
 
    return wrap

 

order 앱에서 views.py 수정하기 

odrder 앱에있는 views.py를 아래와 같이 수정해주세요

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from django.shortcuts import render, redirect
from django.views.generic.edit import FormView
from django.views.generic import ListView
from django.utils.decorators import method_decorator
from fcuser.decorators import login_required
from .forms import RegisterForm
from .models import Order
# Create your views here.
 
@method_decorator(login_required, name='dispatch')
class OrderCreate(FormView):
    form_class = RegisterForm
    success_url = '/product/'
 
    def form_invalid(self, form):
        return redirect('/product/' + str(form.product))
 
    def get_form_kwargs(self**kwargs):
        kw = super().get_form_kwargs(**kwargs)
        kw.update({
            'request'self.request
        })
        return kw
 
@method_decorator(login_required, name='dispatch')
class OrderList(ListView):
    template_name = 'order.html'
    context_object_name = 'order_list'
 
    def get_queryset(self**kwargs):
        queryset = Order.objects.filter(fcuser__email=self.request.session.get('user'))
        return queryset
 
 

from django.utils.decorators import method_decorator 

from fcuser.decorators import login_required

를 추가해주시고
@method_decorator(login_required, name='dispatch')
를 함수위에 써주시면 됩니다. 

 

logout 기능 추가하기

fcuser 앱의 views.py 앱에서 아래와 같이 소스코드를 수정해주세요 

 

def logout(request): 함수를 추가해주시면 됩니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from django.shortcuts import render, redirect
from django.views.generic.edit import FormView
from .forms import RegisterForm, LoginForm
 
# Create your views here.
 
 
def index(request):
    return render(request, 'index.html', { 'email': request.session.get('user') })
 
class RegisterView(FormView):
    template_name = 'register.html'
    form_class = RegisterForm
    success_url = '/'
 
class LoginView(FormView):
    template_name = 'login.html'
    form_class = LoginForm
    success_url = '/'
 
    def form_valid(self, form):
        self.request.session['user'= form.email
        
        return super().form_valid(form)
 
def logout(request):
    if 'user' in request.session:
        del(request.session['user'])
 
    return redirect('/')

 

urls.py 수정하기 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from django.contrib import admin
from django.urls import path
from fcuser.views import index, logout, RegisterView, LoginView
from product.views import ProductList, ProductCreate, ProductDetail
from order.views import OrderCreate, OrderList
 
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', index),
    path('logout/', logout),
    path('register/', RegisterView.as_view()), #클래스는 .as_view() 를 해주어야 함
    path('login/', LoginView.as_view()),
    path('product/', ProductList.as_view()),
    path('product/<int:pk>/', ProductDetail.as_view()),
    path('product/create/', ProductCreate.as_view()),
    path('order/', OrderList.as_view()),
    path('order/create/', OrderCreate.as_view()),
]
 

from fcuser.views imprort 에서 logout 을 추가해주시고 

path('logout/', logout), 추가 해주시면 됩니다.

 

procudt 앱에서 views.py 수정하기

아래와 같이 소스 코드를 수정해 주세요

import와 decorator 추가 해주시면 됩니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from django.views.generic.edit import FormView
from django.utils.decorators import method_decorator
from fcuser.decorators import admin_required
from .models import Product
from .forms import RegisterForm
from order.forms import RegisterForm as OrderForm
# Create your views here.
 
class ProductList(ListView):
    model = Product
    template_name = 'product.html'
    context_object_name = 'product_list'
 
@method_decorator(admin_required, name='dispatch')
class ProductCreate(FormView):
    template_name = 'register_product.html'
    form_class = RegisterForm
    success_url = '/product/'
 
class ProductDetail(DetailView):
    template_name = 'product_detail.html'
    queryset = Product.objects.all()
    context_object_name = 'product'
 
    def get_context_data(self**kwargs):
        context = super().get_context_data(**kwargs)
        context['form'= OrderForm(self.request)
        return context
 
 
 
 

 

fcuser 앱에서 models.py 수정하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from django.db import models
 
# Create your models here.
 
class Fcuser(models.Model):
    email = models.EmailField(verbose_name='이메일')
    password = models.CharField(max_length=128, verbose_name='비밀번호')
    level = models.CharField(max_length=8, verbose_name='등급',
        choices=(
            ('admin''admin'),
            ('user''user')
        ))
    register_date = models.DateTimeField(auto_now_add=True, verbose_name='등록날짜')
 
    def __str__(self):
        return self.email 
 
    class Meta:
        db_table = 'fastcampus_fcuser'
        verbose_name = '사용자'
        verbose_name_plural = '사용자'

password 에서 max_length 부분을 128로 바꿔주시고
level 부분을 추가 해주세요

 

자 이제 모델이 바뀌었으니까 
python manage.py makemigrations

 

please select a fix: 가 나오면 

1 누르고 엔터

'user'을 입력해줍니다.

python manage.py migrate

python manage.py runserver 

을 해주세요 

 

127.0.0.1:8000/product/create 를 들어가보시면 들어가지지 않을겁니다. 

안들어 가지는게 정상이구요 

 

127.0.0.1:8000/admin 으로 들어가셔서 FCUSER의 사용자들어가셔서 아이디 선택 하신후 등급을 user에서 admin 으로 올려주세요 

다시 127.0.0.1:8000/product/create 들어가보시면 화면이 제대로 나올겁니다. 

 

그리고 logout 해보신 다음에 127.0.0.1:8000/product 들어가보시면 login 화면이 나올겁니다. 

 

90000 안녕~~~

728x90

댓글