반원 블로그

django - 로그인 기능 수정(2) - 템플릿 if, 유효성 검사 추가 본문

2018~/Django 개인 공부 정리

django - 로그인 기능 수정(2) - 템플릿 if, 유효성 검사 추가

반원_SemiCircle 2019. 9. 8. 21:28

1.HTTP.Method 분류

  • 먼저 views.py에서 로그인시(POST)와 그냥 페이지 방문(GET) 분류를 시켜놓자.

    def login(request):
      if request.method =="POST":
          form = LoginForm(request.POST)
      else:
          form = LoginForm()
      return render(request,'login.html',{'form':form}) #응답 데이터 res_data 전달
    

## 2.로그인 처리
- .is_valid() :정상적인 데이터인지 확인하는 메소드
- .is_valid()를 통해 걸리지는 비정상 데이터의 케이스 : 비밀번호를 입력 안하는 경우 등
- 해당 코드를 구성한 뒤, 만일 정상 데이터라면 session을 이용하여 검증과정을 거친 후 로그인하는 처리를 구현하면된다.
```python
def login(request):
    if request.method =="POST":
        form = LoginForm(request.POST)
        #정상적인 데이터인지 확인
        if form.is_valid():
            return redirect('/') #루트 페이지로 리다이렉트
    else:
        form = LoginForm()
    return render(request,'login.html',{'form':form}) #응답 데이터 res_data 전달

3 에러 메시지 추가

  • views.py에서 LoginForm(requests.POST)로 만들어진 인스턴스를 저장한 변수 form에는 비정상적인 데이터일 경우에는 에러 데이터도 들어있다.

  • 이 에러데이터를 페이지에 출력되도록 해보자.

  • 템플릿 if는 다음처럼 사용한다.

  • 여기까지의 유효성 검사는 '값의 유무'만 되고 있다

      {% if 조건 %}
      코드
      {% endif %}
    <div class="row mt-5">
    <div class="col-12">
        <form method="POST" action=".">
            {% csrf_token %}
            <!-- 원래 로그인 form-group이 있었던 곳 -->
            {% for field in form %}
                <div class="form-group">
                    <label for="{{field.id_for_label}}">{{field.label}}</label>
                    <input type="{{field.field.widget.input_type}}" class="form-control" id="{{field.id_for_label}}" placeholder="{{field.label}}" name="{{field.name}}">
                </div>

                <!-- 에러 메시지가 있을 경우 출력 -->
                {% if field.errors %}
                    <span style="color:red">{{field.errors}}</span>
                {% endif %}
            {% endfor %}

            <button type="submit" class="btn btn-primary">Submit</button>
        </form>
    </div>
</div>

아무것도 입력안하고 로그인 했을 경우

4. 유효성 검사 추가 - 비밀번호

  • 유효성 검사 추가를 위해 forms.py에 정의한 모델 LoginForm 클래스로 간다.
  • def clean(self): 메소드를 정의한다.(오버라이드). 이는 이미 정의되있는 메소드인데, 이게 이미 수행되고 있는 값이 비어있는지(clean) 검사하는 메소드이다.
  • 오버라이드 하므로 super().clean() 메소드를 호출한다.(값 비어있는지 확인)
  • super().clean() 메소드 호출한 뒤, 각 값을 통해 등록된 회원인지 검사하도록 한다.
  • 검증을 하기 위해서 models.py를 참조하여 DB 모델을 나타내는 fuser 클래스를 이용하여 조회한다(이는 예전 로그인 처리 기능과 코드가 같다.)
  • clean 메소드에 들어오는 self에 들어있는 객체에는 add_error()라는 메소드가 있다. 이는 원하는 필드에 에러 메시지(errors) 속성을 추가하는 메소드다.
  • 여기까지하면, 비밀번호 틀렸을 때 추가된 에러 메시지가 self.add_error()로 정의한 정보로 출력된다.
  • 아직 아무것도 입력안했을 때는 영어로된 메시지가 나온다.

5. 유효성 검사 추가 - 값 비었을 때 문구

  • 모델 LoginForm 클래스에서 각 필드를 정의할 때 error_messages= 매개변수에 딕셔너리를 넣어주면 되는데, 'required' 키의 value값으로 문구를 넣어주면 된다.

6. 뷰 작성 - 로그인 처리

  • views.py에서는 이제 "form이 정상적인 데이터(값도 다 있고, 회원id와 비밀번호도 맞는)면 루트페이지로 이동해라"라고만 작성해주면된다.
  • 리다이렉트로 옮겨주기 전에 session 값을 추가해주는 건 여기서 한다.
  • 위 작업 전에 LoginForm 클래스의 clean 메소드에서 "비밀번호가 맞았을 경우" 에 self.user_id라는 속성(변수)를 만들고, 여기에는 현재 매칭되있는 fuser모델의 Primary Key 값을 설정하자.
#forms.py
from django import forms
from .models import Fuser #DB의 Fuser와 데이터 비교를 위한 참조
from django.contrib.auth.hashers import check_password #패스워드 비교를 위한 참조 


class LoginForm(forms.Form):
    username = forms.CharField(max_length=32, label="아이디",
        error_messages={
            'required':"아이디를 입력하세요"
        })
    password = forms.CharField(label="비밀번호", widget=forms.PasswordInput,
        error_messages={
            'required':"비밀번호를 입력하세요"
        } )

    #유효성 검사하는 clean 메소드를 오버라이드
    def clean(self):
        clean_data = super().clean() #역추적해보면 원래 cleaned_data를 리턴하고있다.
        # 비어있지않은 데이터라면
        username = clean_data.get('username') #requestd에서 값 받아오는 것과 유사
        password = clean_data.get('password')

        # 회원 일치 조회
        if username and password : #2개 변수값이 둘다 None이 아니라면
            fuser = Fuser.objects.get(username=username) #기존 DB와 일치하는 Fuser 모델 가져오기

            if not check_password(password, fuser.password) : #비밀번호가 일치안하면
                self.add_error('password','비밀번호가 틀렸습니다.') #password필드에 에러메시지 추가
            else : #일치하면
                self.user_id = fuser.id #현재 일치하는 fuser의 pk(즉 id)를 user_id 변수로 생성해주자.
#views.py의 def login 함수
def login(request):
    if request.method =="POST":
        form = LoginForm(request.POST)
        #정상적인 데이터인지 확인
        if form.is_valid(): #forms.py에 정의한 clean 메소드대로 검증한다.
            #로그인 session 추가
            request.session['user'] = form.user_id #매칭된 fuser모델의 pk를 세션.user로 추가

            return redirect('/') #루트 페이지로 리다이렉트
    else:
        form = LoginForm()
    return render(request,'login.html',{'form':form}) #응답 데이터 res_data 전달

제대로 로그인 하면 로그인된 페이지로 연결된다.( 다시 한번 기존의 로그인 처리 코드 게시글 복습 추천)

Comments