Django 6일차 TIL

김민지·2023년 9월 4일
0

Django

목록 보기
6/11

Authentication 인증시스템 구축

views.py

def hello_world(request):

    if request.user.is_authenticated:
        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'))

Decorator를 이용한 코드 간소화

from datetime import datetime

def decorator(func):
	def decorated():
      print(datetime.now())
      func()
      print(datetime.now())
      
    return
@decorater

함수를 받아 함수의 앞, 뒤, 앞뒤를 꾸며준다. 함수 내부에 직접적인 영향은 없다.

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
has_ownership = [account_ownership_required, login_required]

@method_decorator(has_ownership, 'get')
@method_decorator(has_ownership, 'post')

superuser, media 관련 설정

superuser 설정

python manage.py createsuperuser

media 설정

settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

터미널

pip install pillow

Profileapp 시작 그리고 ModelForm

Profile app 생성

python manage.py startapp profileapp

setting.py에서 profile app 명시
urls.py에서 경로 연결

profileapp/models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

연결되어 있는 user객체가 delete될 때 그와 연결되어 있는 profile 객체가 어떤 행동을 결정할지 정책 부분을 담당한다.

Form

class ProfileCreationForm(ModelForm):
	class Meta:
    	model =  Profile
        fields = ['image', 'nickname', 'message']

ModelForm을 상속받은 후에 어떤 모델을 사용할 것인지, 어떤 필드를 입력할 수 있게 만들 것인지 설정만 하면 model이 form으로 변화한다.


profileapp 구현 시작

필요한 뷰를 만들고 form_vaild라는 함수를 적용했다.

    def form_valid(self, form): #form_vaild 함수를 통해서 로직을 수행하고 성공적으로 마치면 알아서 success_url에 정의한 페이지로 이동한다.
        temp_profile = form.save(commit=False) # 임시저장
        temp_profile.user = self.request.user
        temp_profile.save()
        return super().form_valid(form) #슈퍼클래스, 즉 부모인 CreateView를 상속

detail.html

	{% if target_user.profile %}
        <h2 style="font-family: 'NanumSquareB' ">
            {{ target_user.profile.nickname }}
        </h2>
    {% else %}
        <a href="{% url 'profileapp:create' %}">
            <h2 style="font-family: 'NanumSquareB'">
                Create Profile
            </h2>
        </a>
    {% endif %}

타겟 유저의 프로필이라면 프로필앱에서 닉네임을 보여준다. 그게 아니면 프로필을 만들도록 Create Profile을 띄운다.


profileapp 마무리

urls.py 경로, static 설정

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('accountapp.urls')),
    path('profiles/', include('profileapp.urls')),

] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

detail.py

<a href="{% url 'profileapp:update' pk=target_user.profile.pk %}">
                    edit
                </a>

프로필 닉네임을 변경할 수 있도록 edit 추가

 <img src="{{ target_user.profile.image.url }}" style="height: 12rem; width: 12rem; border-radius: 20rem; margin-bottom: 2rem;">

프로필 사진의 경로와 css 추가

decorators.py

from django.http import HttpResponseForbidden

from profileapp.models import Profile


def profile_ownership_required(func):
    def decorated(request, *args, **kwargs):
        profile = Profile.objects.get(pk=kwargs['pk'])
        if not profile.user == request.user:
            return HttpResponseForbidden()
        return func(request, *args, **kwargs)
    return decorated

유저의 프로필이 요청한 유저와 같지 않다면 forbidden 반환

views.py

@method_decorator(profile_ownership_required, 'get')
@method_decorator(profile_ownership_required, 'post')

결과 화면


🤓 새로 알게된 점, 어려웠던 점

    def form_valid(self, form): #form_vaild 함수를 통해서 로직을 수행하고 성공적으로 마치면 알아서 success_url에 정의한 페이지로 이동한다.
        temp_profile = form.save(commit=False) # 임시저장
        temp_profile.user = self.request.user
        temp_profile.save()
        return super().form_valid(form) #슈퍼클래스, 즉 부모인 CreateView를 상속

이 부분을 이해하고 싶어 나름 주석까지 달아보며 열심히 노력했지만 확실하게 아는 느낌이 없다.
임시저장의 개념이 와닿지 않는다. 뭘 임시저장 하는걸까?
(주석을 달며 참고한 티스토리: https://iamthejiheee.tistory.com/69)

profile
안녕하세요

0개의 댓글