웹개발/[점프 투 플라스크]

[점프 투 플라스크] 회원가입,로그인,로그아웃 등 구현

2soon2soon 2024. 4. 15. 11:23

네비게이션 바

부트스트랩 이용해서 base.html에 코드 추가하면 됨 not difficult

이때 base.html에 코드 추가할때 include기능을 사용.

include 기능? 프로그램 유지 보수를 용이하게 하기 위해 따로 navbar.html이라는 파일에 네비게이션바를 구현하고 include기능을 통해 base.html에 navbar.html 코드 전체를 삽입가능

{% include "navbar.html" %}

 

페이징

page = request.args.get('page', type=int, default=1)

이전페이지에서 요청한URL로 page값 가져올 때 사용. int형이며, 디폴트값은 1

http://localhost:5000/question/list/?page=5

이런식으로 url이 요청되면 page값에 5가 저장. 이전페이지에서 page값이 없는 채로 요청되면 디폴트값인 1이 저장

 

question_list = question_list.paginate(page=page, per_page=10)

의 경우는 한페이지당 10개제한으로 페이징할 것을 의미하고 page=page는 현재 조회할 페이지를 의미함.

question_list에 원래의 question_list를 Pagination객체로 변경하고 page와 per_page속성 정보를 넣고 할당.

 

paginate함수를 쓰는 순간, question_list는 Pagination객체가 된다. 

따라서 html의 모든 question_list를 수정해줘야함.

 

템플릿필터를 언제 만드는가

예를들어 html파일에서 평균평점(float)를 소숫점둘째짜리까지 반올림해서 나타내고싶을 때

html의 문법으로는 이를 나타낼 방법이 없음.

이때 파이썬의 문법으로는 이를 구현 가능해 

파이썬의 문법으로 템플릿필터를 만들어

html파일에서 {{ song.average_rate|round2 }}

이런 식으로 소수점둘째짜리까지 반올림해서 나타낼 수 있음.

즉 html의 문법으로 구현할 수 없는 것을 파이썬에서 구현하고 싶을 때 템플릿 필터를 만들어 사용함.

 

 

 

------

로그인, 로그아웃

 

request는 한 url요청에서만 유효하지만
session은 여러 url요청에도 유효함. 페이지를 여러번 갈아타도 유효하다는 거임
따라서 session은 로그인정보를 저장할때 씀

session['user_id'] = user.id
user_id라는 key에 아이디에해당하는 값을 저장

로그인여부확인하는 함수
@bp.before_app_request
def load_logged_in_user():
    user_id = session.get('user_id')
    if user_id is None:
        g.user = None
    else:
        g.user = User.query.get(user_id)

before_app_Request 애너테이션이 적용됐으므로 '파이보의 모든' 라우팅함수가 실행되면 그 앞에 자동으로 실행됨
따라서 g.user를 이제 자유롭게 사용가능. 심지어 g.user은 유저'객체'임. 유저명, 이메일도 얻을 수 있다는 뜻
g는 플라스크의 컨텍스트 변수임. 
g는 근데 request처럼 한 url요청에서만 유효함.
따라서 로그아웃을 한 경우 session을 초기화하는데 
로그아웃 이후 url요청이 들어오면 session값을 읽지 못하므로 g.user값이 none이 됨.

 

-----

특정 모델의 데이터들을 이미 데이터베이스에 추가했는데

새로운 모델의 속성을 nullable=False로 추가하면, 기존의 데이터들이 null값이여서 flask db upgrade하면 오류뜸

nullable=True, server_default='1'이런식으로 디폴트값을 설정해서 정의한다음, falsk db migrate/upgrade한 뒤,

모델의 속성을 nullable=False로 바꿔주면 됨!

 

@login_required 데코레이터

def login_required(view):
    @functools.wraps(view)
    def wrapped_view(*args, **kwargs):
        if g.user is None:
            _next = request.url if request.method == 'GET' else ''
            return redirect(url_for('auth.login', next=_next))
        return view(*args, **kwargs)
    return wrapped_view

문법이 복잡해보이는데 교재에 디테일한 설명이 없음.

g.user가 None이면(로그아웃 상태면) _next에 원래 요청했던 페이지를 담아서 next변수에 저장하고  auth.login라우팅함수 로 보냄(로그인 페이지로 보냄)

그리고 auth.login라우팅함수에서 로그인시키고, 사용자가 로그인하면 next변수에 담겨있는 페이지로 이동시킴

 

이정도로만 이해해놓자

 

 

<textarea {% if not g.user %}disabled{% endif %} name="content" id="content" class="form-control" rows="10">

이런식으로 textarea에 disabled작성하면 글 자체를 입력못하게 막을 수 있음.