Pet-Project-web-아이피-로그인 기능

개요

게시글에 아이피를 추가하고 관련 기능을 추가함

기능

아이피 관련

  • 아이피를 추가하는 것은 다음 이유가 있다.

    1. 추천, 비추천 기능에 있어서 중복을 막기 위함
    2. 비로그인 유저,로그인 유저를 구분하기 위함
      user(ip) <- 비로그인 유저
      user <- 로그인 유저
  • 로그인한 유저의 경우에는 로그인 정보로 구분을 하는데 비로그인 유저의 글은 ip로 구분하는 것은 또 아니다.

    밖에서 글을 작성하고 집에와서 글을 수정하거나 삭제하는 것이 가능해야 한다고 생각했기 때문이다.

로그인 관련

  • 로그인 기능을 추가함으로써 변경되는 사항들
    1. 댓글 작성 로그인 유무에 따라 삭제
      1. 대댓글 작성 로그인 유무에 따라 삭제
    2. 글쓰기 로그인 유무에 따라 수정, 삭제

예시 그림

ip예제_01

[비로그인 유저인 경우 ip를 출력하는 모습]

ip예제_02

[로그인 유무에 따라 ip가 출력되고 안출력되는 모습]

코드

ip 관련

  • 사용자의 ip 가져오기

    1
    2
    3
    4
    5
    def get_covered_ip():
    ip = socket.gethostbyname(socket.gethostname())
    front_ip = ip.split('.')[0]
    back_ip = ip.split('.')[1]
    return front_ip + '.' + back_ip

    위 코드를 실행하면 ip에 123.456.789.876~ 같은 형식으로 ip가 출력된다.

    실제로 보여주는 ip 형식은 123.456 형식을 원하기 때문에 split(‘.’)을 이용하여 일부를 제거했다.

로그인 관련

  • 로그인 구현

    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
    @login_bp.route('/login/<string:before_page>',methods=['GET','POST'])
    def login(before_page=None):
    form = UserLoginForm()
    if request.method == 'POST' and form.validate_on_submit():
    error = None
    db = Database()
    user = db.executeAll("SELECT id,password FROM user WHERE id = '%s'" % (form.username.data))

    if len(user) == 0:
    user = 0
    else:
    password = user[0]['password']
    user = user[0]['id']

    if user == 0:
    error = "존재하지 않는 사용자입니다"

    elif not password == form.password.data:
    error = "비밀번호가 올바르지 않습니다."

    if error is None:
    session.clear()
    session['user_id'] = user
    print("이전 페이지:",before_page)
    if before_page == 'checklist':
    return redirect(url_for(before_page+'.checklist'))
    elif before_page != None:
    return redirect(url_for(before_page+'.list'))
    return redirect(url_for('main.index'))

    flash(error)
    return render_template('/main/login.html',form=form)

    우선 login 페이지(html)에서 post 형태로 통신이 들어오면, 입력된 form이 login form 규격에 맞는지 체크한다.

    맞다면 데이터베이스에서 로그인 정보를 가져온다.

    실제로 로그인 정보가 일치하면 세션에 로그인 정보를 갱신하게 된다.

  • 로그인 유무 확인

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @login_bp.before_app_request
    def load_logged_in_user():
    user_id = session.get('user_id')
    if user_id is None:
    g.user = None
    g.idx = None
    else:
    db = Database()
    g.user = db.executeOne("SELECT id,idx FROM user WHERE id = '%s' " % (user_id))
    g.idx = g.user['idx']
    g.user = g.user['id']

    위 코드에서 before_app_request는 이름 그대로 어떤 request를 하기 전에 항상 거치는

    메소드를 명시하는 것이다.

    앞서 본 코드에서 로그인을 하게되면 session에 값이 갱신되고 로그인 한 후에는

    항상 load_logged_in_uer() 메소드를 거쳐 g(플라스크의 전역변수 정도로 이해)의 전역변수를 지정해주는 식으로

    로그인을 구분짓을 수 있다.

    • 장고 템플릿에서의 예
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    {% if g.user %}
    Hello {{g.user}}<br>
    <ul class="login">
    <li><a href="/logout" style="margin-bottom:10px;" class="button big">Logout</a></li>
    </ul>

    {% else %}
    <div class="btns">
    <div class="loginArea">
    <li>
    {% if request.path != "/login" %}
    <a href="/login" class="button big" style="margin-right:10px;">
    <span style = " color:white;">
    Login
    </span>
    </a>
    {% endif %}

    중요한것은
    {{g.user}}로 로그인을 구분지어 이에따라 보여지는 html을 수정할 수 있다는 점이다.

    위는 다음과 같이 출력된다.

    ip예제_01

  • 백엔드 상 예제

    1
    2
    3
    4
    5
    6
    7
    if loginUser == 1 and (username==session.get('user_id')):
    content_title = data[0]['board_content_title']
    content_text = data[0]['board_content']
    username = data[0]['write_user_name']
    password = "****"
    ...이하 생략
    위 코드는 수정버튼을 눌렀을 때를 생각해보면

    로그인한 유저 = 게시글을 작성하는 유저를 확인하는 부분이다

    조건문의 username은 앞서 데이터베이스에서 해당 게시글을 작성한 유저를 의미하고

    session.get(‘user_id’)를 통해 현재 로그인한 유저와 비교한다.

    참고로 loginUser는 게시글을 작성한 유저의 로그인 유무를 의미하는 변수이다.

이로써 게시판에 로그인,ip 기능을 적용했다.
아무래도 플라스크를 이용하여 웹 페이지를 구현하면

html이라던가 form이라던가 세부적인 사항도 많이 남아 있지만

전체 코드를 담기에는 의미없는 반복, 세부사항이 너무 많아 생략한다는 점 양해 바란다.

Pet-Project-web-0627-근황

개요

웹에 클론코딩 페이지를 추가하기까지의 정리

현황

  1. 게시글 리스트에 작성자 추가

    1. 비로그인인 경우 작성자에 ip가 표시됨(ip 일부)
    2. 로그인한 유저의 경우 작성자에 ip 미표시
  2. 로그인 기능 적용

    1. 로그인한 유저가 작성한 글은 해당 유저만 삭제가능
    2. 로그인한 유저는 비로그인 유저의 삭제,수정기능 이용불가
    3. 비로그인 유저의 글 수정 삭제는 비밀번호 입력
    4. 로그인 유저의 글 수정 삭제는 동일 유저라면 비밀번호 입력 X
    5. 댓글,대댓글에도 적용시킴
  3. 검색기능

  4. 페이징기능

  5. 추천,비추천 기능 추가

  6. 댓글,대댓글 기능 추가

검색,페이징 기능

검색 및 페이징

작성자 추가, 로그인 적용(ip 유무로 로그인 비로그인 구분)

작성자 추가, 로그인 적용

댓글 관련

댓글 관련

소스 코드 및 설명

앞으로 추가 및 링크 추가 예정!

향후 목표

  1. 사진 업로드 기능(글쓰기)

  2. 프로필 기능

web-add-clone-board-modify-del


title: Pet-Project-web-수정 및 삭제기능 추가
category: pet project
tags: pet project

date: 2021-06-09 4:55:01

개요

웹에 클론코딩 페이지를 추가하기까지의 정리

현황

게시글 수정 및 게시글 삭제를 추가하였다.

게시글 수정,삭제 버튼

[글쓰기 버튼 추가 및 작성일시 추가]
게시글 수정 화면
[글쓰기 눌렀을 때 화면]

소스 코드 수정 현황

  1. clone_board.py
  2. board_add.html
  3. board_content.html

clone_board.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
@clone_board_bp.route('/del/<int:board_content_idx>/')
def delContent(board_content_idx):
db = Database()
db.execute("""DELETE FROM board_content_table WHERE board_content_idx = %s""" %str(board_content_idx))
db.commit()
return redirect(url_for("clone_board.list"))


@clone_board_bp.route('/modify/<int:board_content_idx>/',methods=['POST','GET'])
def modify(board_content_idx):
db = Database()
data = db.executeAll("""SELECT * FROM board_content_table WHERE board_content_idx = %s""" %str(board_content_idx))

if request.method == 'POST':
form = ContentAddForm()
if form.validate_on_submit():
db.execute("""UPDATE board_content_table SET write_time='%s',board_content_title='%s',board_content='%s' WHERE board_content_idx = '%s'""" % (datetime.now(),form.content_title.data,form.content_text.data,str(data[0]['board_content_idx']) ))
db.commit()
return redirect(url_for('clone_board.content',board_content_idx=board_content_idx))
else:
form = ContentAddForm(content_title=data[0]['board_content_title'],content_text=data[0]['board_content'])
return render_template('/main/board_add.html',form=form,board_content_idx=board_content_idx)


clone_board.py 설명

  • 일부 생략된 코드임을 유의
  • 삭제 버튼을 누르면 DB에서 삭제
  • 수정 버튼을 누르면 수정창(게시글 작성 재활용)을 띄워줌
  • 수정창에서 등록을 눌렀다면(request = POST인 경우) db에 업데이트 해주고 수정된 내용을 보여줌

board_add.html 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
생략
<div class="container my-3">
<form method="post" class="post-form">
{{ form.csrf_token }}
{% include "checklist_form_errors.html" %}
Title:&nbsp
<input type="content_title" class="form-control" name="content_title" id="content_title" value={{ form.data.content_title or ''}}>

<form action="{{ url_for('clone_board.list',board_content_idx=board_content_idx) if form.data.content_text else url_for('clone_board.list') }}" method="post">

<label for="content_text" style="font-size:16px;">Content:</label>
<textarea name="content_text" id="content_text" rows="15">{{form.data.content_text or ''}}</textarea>
<input type="submit" style="font-size:16px;" value="등록">

</form>
</form>

생략

board_add.html 설명

  1. 조건문으로 수정모드일때와 글작성 모드를 forms의 값 유무로 판단하여 버튼을 눌렀을 때 연결할 url을 설정해줌

board_content.html 코드

1
2
3
4
5
6
7
8
9
10
<div class="btns">   
<div class="modify">
<a href="{{ url_for('clone_board.modify',board_content_idx=content[0]['board_content_idx'])}}"
class="button">수정</a>
</div>
<div class="delete">
<a href="{{ url_for('clone_board.delContent',board_content_idx=content[0]['board_content_idx']) }}"
class="button"> 삭제 </a>
</div>
</div>

board_content_html 설명

  1. 수정,삭제버튼 추가

향후 목표

  1. 기능 손보기
    1. 부트스트랩 변경(디자인 수정)
  2. 글 수정기능
    1. 패스워드 기능 추가
  3. 글 삭제
    1. 패스워드 기능 추가
  4. 사진 업로드 기능(글쓰기)
  5. 작성자 이름 추가(닉네임)
  6. 글 댓글 기능 추가
    1. 댓글 작성자 이름
    2. 댓글 패스워드
    3. 댓글 수정, 삭제

Pet-Project-web-게시글 추가 기능 및 날짜 추가

개요

웹에 클론코딩 페이지를 추가하기까지의 정리

현황

게시글 추가와 게시글에 날짜를 추가하였다.
게시글 화면

[글쓰기 버튼 추가 및 작성일시 추가]
게시글 작성 화면
[글쓰기 눌렀을 때 화면]

소스 코드 수정 현황

  1. clone_board.py
  2. board.html

clone_board.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
from threading import main_thread
from flask import Blueprint, request, render_template, flash, redirect, url_for, g,session
from app.module.dbModule import Database
from app.forms.forms import ContentAddForm, UserAddCheck
from datetime import datetime

clone_board_bp = Blueprint('clone_board',__name__,url_prefix='/clone_board')

@clone_board_bp.route('/list',methods=['POST','GET'])
def list():
db = Database()
content_list = db.executeAll("SELECT * FROM board_content_table")
print(content_list)
return render_template('/main/board.html',content_list=content_list)



@clone_board_bp.route('/add',methods=['POST','GET'])
def add():
form = ContentAddForm()
title = form.content_title.data
text = form.content_text.data
if request.method == 'POST' and not form.validate_on_submit() and ((title == "") or (text == "")):
error = "데이터 양식이 맞지 않습니다"
flash(error)
elif request.method == 'POST' and not((title == "") or (text == "")):
db = Database()
db.execute("""INSERT INTO board_content_table (board_content,board_content_title,write_time) VALUES ('%s','%s','%s')""" % (text, title,datetime.now()))
db.commit()
return redirect(url_for("clone_board.list"))

return render_template('/main/board_add.html',form=form)

clone_board.py 설명

  1. 게시글 리스트를 보여주는 list 페이지와 게시글 추가 버튼을 눌렀을 때의 add 페이지로 분리
  2. 게시글 리스트 페이지에서는 항상 디비로부터 가져온 정보를 모두 출력함(아직 페이징 기능 미구현)
  3. 게시글 추가 페이지에서는 제목과 내용을 입력하면 데이터베이스에 추가함
    • 제목이나 내용을 입력하지 않으면 에러 출력함
  4. 데이터베이스에 제대로 입력됐다면 list 페이지로 재연결해줌

    clone_board.html 코드

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
35
36
{% extends 'main/clone_base.html' %}
{% block content %}

<html>
<body>
<div class="container my-3">
<table class="table">
<thead>
<tr class="thead-dark">
<th>번호</th>
<th>제목</th>
<th>작성일시</th>

</tr>
</thead>
<tbody>
{% if content_list %}
{% for content in content_list %}
<tr>
<td>{{ content['board_content_idx'] }}</td>
<td>
{{ content['board_content'] }}
</td>
<td>{{ content['write_time'] }}</td>

</tr>


</table>
<div class="btns">
<li><a href="/clone_board/add" class="button big">글쓰기</a></li>
</div>


이하 생략

clone_board.html 설명

  1. 리스트 페이지의 작성글 인덱스,내용,작성 일시를 출력
  2. 글쓰기 버튼 추가

clone_board_add.html 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
생략
<div class="container my-3">
<form method="post" class="post-form">
{{ form.csrf_token }}
{% include "checklist_form_errors.html" %}
Title:&nbsp
<input type="content_title" class="form-control" name="content_title" id="content_title">

<form action="{{ url_for('clone_board.add') }}" method="post">

<label for="content_text" style="font-size:16px;" >Content:</label>
<textarea name="content_text" id="content_text" rows="15"></textarea>
<input type="submit" style="font-size:16px;" value="등록">

</form>
</form>
생략

clone_board_add.html 설명

  1. 에러 출력 관련 처리 위한 코드 추가
  2. 제목과 내용 입력란 추가
  3. 등록 버튼을 누르면 forms 정보와 함께 clone_board add 메소드로 이동

향후 목표

  1. 기능 손보기
    1. 부트스트랩 변경(디자인 수정)
  2. 글 수정기능
    1. 부가적으로 패스워드 필요
  3. 글 삭제
    1. 부가적으로 패스워드 필요
  4. 사진 업로드 기능(글쓰기)
  5. 작성자 이름 추가(닉네임)