28강
Decorator 패턴을 이용해서 자주 쓰이는 코드 간소화
from datetime import datetime
def function1():
print(datetime.now())
print("Function 1 Start")
print(datetime.now())
def function2():
print(datetime.now())
print("Function 2 Start")
print(datetime.now())
def function3():
print(datetime.now())
print("Function 3 Start")
print(datetime.now())
->
def decorator(func):
def decorated():
print(datetime.now())
func()
print(datetime.now())
return decorated
from datetime import datetime
...
@decorator
def function1():
print("Function 1 Start")
@decorator
def function2():
print("Function 2 Start")
@decorator
def function3():
print("Function 3 Start")
아주 간단하게 바뀜 ㅋ
views.py
def hello_world(request):
if request.method == "POST":
temp = request.POST.get('hello_world_input')
new_hello_world=HelloWorld()
new_hello_world.text = temp
new_hello_world.save()
return HttpResponseRedirect(reverse('accountapp:hello_world'))
else:
hello_world_list = HelloWorld.objects.all()
return render(request, 'accountapp/hello_world.html', context={'hello_world_list':hello_world_list})
else:
return HttpResponseRedirect(reverse('accountapp:login'))
여기서
@login_required가 로그인 했는지 안했는지, 리턴까지 해줌
즉, @login_required가 decorator임. 이미 제공하는거지.
class AccountUpdateView(UpdateView):
model = User # 상속
context_object_name = 'target_user'
form_class = AccountUpdateForm # 장고가 기본제공
success_url = reverse_lazy('accountapp:hello_world')
template_name = 'accountapp/update.html'
def get(self, *arg, **kwargs):
if self.request.user.is_authenticated and self.get_object() == self.request.user:
return super().get(*arg, **kwargs)
else:
return HttpResponseForbidden()
def post(self, *arg, **kwargs):
if self.request.user.is_authenticated:
return super().get(*arg, **kwargs)
else:
return HttpResponseForbidden()
이번엔 AccountUpdateView를 보자.
여기서 get이랑 post는 AccountUpdateView class가 제공하는 메소드야
(클래스에 포함된 function : 메소드, 일반적인 function : 함수. 라고 부르네?)
그니까 머 @login_required 이런거 안돼
views.py
class AccountUpdateView(UpdateView):
model = User # 상속
context_object_name = 'target_user'
form_class = AccountUpdateForm # 장고가 기본제공
success_url = reverse_lazy('accountapp:hello_world')
template_name = 'accountapp/update.html'
def get(self, *arg, **kwargs):
if self.request.user.is_authenticated and self.get_object() == self.request.user:
return super().get(*arg, **kwargs)
else:
return HttpResponseForbidden()
def post(self, *arg, **kwargs):
if self.request.user.is_authenticated:
return super().get(*arg, **kwargs)
else:
return HttpResponseForbidden()
데코레이터 써버리면?
@method_decorator (login_required, 'get')
@method_decorator (login_required, 'post')
class AccountUpdateView(UpdateView):
model = User # 상속
context_object_name = 'target_user'
form_class = AccountUpdateForm # 장고가 기본제공
success_url = reverse_lazy('accountapp:hello_world')
template_name = 'accountapp/update.html'
인증 과정은 빠지긴 했는데, 로그인 과정은 포함이 된거야.
@method_decorator (login_required, 'get')
@method_decorator (login_required, 'post')
class AccountUpdateView(UpdateView):
model = User # 상속
context_object_name = 'target_user'
form_class = AccountUpdateForm # 장고가 기본제공
success_url = reverse_lazy('accountapp:hello_world')
template_name = 'accountapp/update.html'
@method_decorator (login_required, 'get')
@method_decorator (login_required, 'post')
class AccountDeleteView(DeleteView):
model = User
context_object_name = 'target_user'
success_url = reverse_lazy('accountapp:login')
template_name = 'accountapp/delete.html'
자... 그럼 그걸 하기 위해서는, custom decorator를 만들어야돼.
pragmatic/accountapp/templates/accountapp/decorators.py
from django.contrib.auth.models import User
from django.http import HttpResponseForbidden
def account_ownership_required(func):
def decorated(request, *args, **kwargs):
user = User.objects.get(pk=kwargs['pk'])
if not user == request.user:
return HttpResponseForbidden()
return func(request, *args, **kwargs)
return decorated
? 몽미
@method_decorator (login_required, 'get')
@method_decorator (login_required, 'post')
@method_decorator (account_ownership_required, 'get')
@method_decorator (account_ownership_required, 'post')
class AccountUpdateView(UpdateView):
model = User # 상속
context_object_name = 'target_user'
form_class = AccountUpdateForm # 장고가 기본제공
success_url = reverse_lazy('accountapp:hello_world')
template_name = 'accountapp/update.html'
@method_decorator (login_required, 'get')
@method_decorator (login_required, 'post')
@method_decorator (account_ownership_required, 'get')
@method_decorator (account_ownership_required, 'post')
class AccountDeleteView(DeleteView):
model = User
context_object_name = 'target_user'
success_url = reverse_lazy('accountapp:login')
template_name = 'accountapp/delete.html'
근데 method_decorator도 기니까
def hello_world 위에다가
has_ownership = [account_ownership_required, login_required]
하면
@method_decorator (has_ownership, 'get')
@method_decorator (has_ownership, 'post')
class AccountUpdateView(UpdateView):
model = User # 상속
context_object_name = 'target_user'
form_class = AccountUpdateForm # 장고가 기본제공
success_url = reverse_lazy('accountapp:hello_world')
template_name = 'accountapp/update.html'
@method_decorator (has_ownership, 'get')
@method_decorator (has_ownership, 'post')
class AccountDeleteView(DeleteView):
model = User
context_object_name = 'target_user'
success_url = reverse_lazy('accountapp:login')
template_name = 'accountapp/delete.html'
이렇게 할 수가 있음
29강
superuser, media 관련 설정
superuser 계정이 있어야 들어갈 수 있어
이렇게 들어가짐.
이번에는 media 관련 설정을 할꺼야
이거 다음에 만들게 profile app인데, 거기에 이미지가 들어가거든
그래서 이미지를 올릴 수 있게 할거야
settings.py 맨 밑에
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL은 주소창에 media 이하의 경로로 접근해야 실제 미디어 파일에 접근할 수 있다.
MEDIA_ROOT는 media 파일 서버에 올렸을 때, 어느 경로에 올라갈건지.
장고에서 이미지를 관리할 때 필요한 라이브러리가 있어
필로우라고 함
pip install pillow
설치하고 강의 마무리
최근댓글