• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    해결됨

오류 나는 부분이 있어서 다시 질문 드립니다! 도와주세요! (join 로그인시 백지, 몽고db 이메일주소 null 표시)

22.04.09 00:04 작성 조회수 124

2

안녕하세요

 

웹개발 입문부분 강좌를 거의다 들었는데.. 오류가 나는 부분이 있어서.. 질문을 올립니다!

 

문제는..join 로그인 하면 몽고db에서 이메일 주소가 null로 표시가 되서.. 동작이 되지 않는점이 있습니다..

 

비슷한 증상을 찾기 어려워서 질문 남깁니다!

 

-화면-

-join-

 

-mongoDB- 

-list-

-list 로그인 페이지-

next_url  << 이게 문제가 나왔었는데 다른 코드들 참고 했는데 해결은 됬습니다.

-run.py-

from flask import Flask
from flask import request
from flask import render_template
from flask_pymongo import PyMongo
from bson.objectid import ObjectId
from flask import abort
from flask import redirect
from flask import url_for
from flask import flash
from flask import session
from functools import wraps
import math

import time
from datetime import datetime, timedelta

app = Flask(__name__)
app.config["MONGO_URI"] = "mongodb://localhost:27017/myweb"
app.config["SECRET_KEY"] = "abcd"
app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(minutes=30)
mongo = PyMongo(app)


def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if session.get("id") is None or session.get("id") == "":
            return redirect(url_for("member_login", next_url=request.url))
        return f(*args, **kwargs)
    return decorated_function


@app.template_filter('formatdatetime')
def format_datetime(value):
    if value is None:
        return ""

    now_timestamp = time.time()
    offset = datetime.fromtimestamp(
        now_timestamp) - datetime.utcfromtimestamp(now_timestamp)
    value = datetime.fromtimestamp((int(value) / 1000)) + offset
    return value.strftime('%Y-%m-%d %H:%M:%S')


@app.route("/list")
def lists():
    # 페이지 값 (값이 없는 경우 기본값는 1)
    page = request.args.get("page", 1, type=int)
    # 한페이지당 몇개의 게시물을 출력할지
    limit = request.args.get("limit", 5, type=int)

    search = request.args.get("search", -1, type=int)
    keyword = request.args.get("keyword", type=str)

    # 최종적으로 완성된 쿼리를 만들 변수
    query = {}
    # 검색어 상태를 추가할 리스트 변수
    search_list = []

    if search == 0:
        search_list.append({"title": {"$regex": keyword}})
    elif search == 1:
        search_list.append({"contents": {"$regex": keyword}})
    elif search == 2:
        search_list.append({"title": {"$regex": keyword}})
        search_list.append({"contents": {"$regex": keyword}})
    elif search == 3:
        search_list.append({"name": {"$regex": keyword}})

    # 검색 대상이 한개라도 존재할 경우 query 변수에 $or 리스트를 쿼리 합니다.
    if len(search_list) > 0:
        query = {"$or": search_list}

    print(query)

    board = mongo.db.board
    datas = board.find({}).skip((page - 1) * limit).limit(limit)

    # 게시물의 총 갯수
    tot_count = board.count_documents({})
    # 마지막 페이지의 수를 구한다.
    last_page_num = math.ceil(tot_count / limit)
    # 페이지 블럭을 5개씩 표기
    block_size = 5
    # 현재 블럭의 위치
    block_num = int((page - 1) / block_size)
    # 블럭의 시작 위치
    block_start = int((block_size * block_num) + 1)
    # 블럭의 끝 위치
    block_last = math.ceil(block_start + (block_size - 1))

    return render_template("list.html", datas=list(datas), limit=limit, page=page, block_start=block_start, block_last=block_last, last_page_num=last_page_num, search=search, keyword=keyword)


@ app.route("/view/<idx>")
@login_required
def board_view(idx):
    # idx = request.args.get("idx")
    if idx is not None:
        page = request.args.get("page")
        search = request.args.get("search")
        keyword = request.args.get("keyword")

        board = mongo.db.board
        # data = board.find_one({"_id": ObjectId(idx)})
        data = board.find_one_and_update({"_id": ObjectId(idx)}, {
            "$inc": {"view": 1}}, return_document=True)

        if data is not None:
            result = {
                "id": data.get("_id"),
                "name": data.get("name"),
                "title": data.get("title"),
                "contents": data.get("contents"),
                "pubdate": data.get("pubdate"),
                "view": data.get("view"),
                "writer_id": data.get("writer_id", "")
            }

            return render_template("view.html", result=result, page=page, search=search, keyword=keyword)
    return abort(404)


@ app.route("/write", methods=["GET", "POST"])
def board_write():
    if session.get("id") is None:
        return redirect(url_for("member_login"))

    if request.method == "POST":
        name = request.form.get("name")
        title = request.form.get("title")
        contents = request.form.get("contents")
        print(name, title, contents)

        current_utc_time = round(datetime.utcnow().timestamp() * 1000)
        board = mongo.db.board
        post = {
            "name": name,
            "title": title,
            "contents": contents,
            "pubdate": current_utc_time,
            "writer_id": session.get("id"),
            "view": 0,
        }

        x = board.insert_one(post)
        print(x.inserted_id)
        return redirect(url_for("board_view", idx=x.inserted_id))
    else:
        return render_template("write.html")


@app.route("/join", methods=["GET", "POST"])
def member_join():
    if request.method == "POST":
        name = request.form.get("name", type=str)
        email = request.form.get("email", type=str)
        pass1 = request.form.get("pass", type=str)
        pass2 = request.form.get("pass2", type=str)

        if name == "" or email == "" or pass1 == "" or pass2 == "":
            flash("입력되지 않은 값이 있습니다.")
            return render_template("join.html")
        if pass1 != pass2:
            flash("비밀번호가 일치하지 않습니다.")
            return render_template("join.html")

        members = mongo.db.members
        cnt = members.count_documents({"email": email})

        if cnt > 0:
            flash("중복된 이메일 주소입니다.")
            return render_template("join.html")

        current_utc_time = round(datetime.utcnow().timestamp() * 1000)

        post = {
            "name": name,
            "email": email,
            "pass": pass1,
            "joindate": current_utc_time,
            "logintime": "",
            "logincount": 0,
        }

        members.insert_one(post)

        return ""
    else:
        return render_template("join.html")


@app.route("/login", methods=["GET", "POST"])
def member_login():

    if request.method == "POST":
        email = request.form.get("email")
        password = request.form.get("pass")
        next_url = request.form.get("next_url")
        members = mongo.db.members
        data = members.find_one({"email": email})

        if data is None:
            flash("회원 정보가 없습니다.")
            return redirect(url_for("member_login"))
        else:
            if data.get("pass") == password:
                session["email"] = email
                session["name"] = data.get("name")
                session["id"] = str(data.get("_id"))
                session.permanent = True
                if next_url is not None:
                    return redirect(next_url)
                else:
                    return redirect(url_for("lists"))
                return redirect(url_for("lists"))
            else:
                flash("비밀번호가 일치하지 않습니다.")
                return redirect(url_for("member_login"))
        return ""
    else:

        next_url = request.args.get("next_url", type=str)
        if next_url is not None:
            return render_template("login.html", next_url=next_url)
        else:
            return render_template("login.html")


@app.route("/edit/<idx>", methods=["GET", "POST"])
def board_edit(idx):
    if request.method == "GET":
        board = mongo.db.board
        data = board.find_one({"_id": ObjectId(idx)})
        if data in None:
            flash("해당 게시물이 존재하지 않습니다.")
            return redirect(url_for("lists"))
        else:
            if session.get("id") == data.get("writer_id"):
                return render_template("edit.html", data=data)
            else:
                flash("글 수정 권한이 없습니다.")
                return redirect(url_for("lists"))
    else:
        title = request.form.get("title")
        contains = request.form.get("contents")

        board = mongo.db.board
        data = board.find_one({"_id": ObjectId(idx)})
        if session.get("id") == data.get("writer_id"):
            board.update_one({"_id": ObjectId(idx)}, {
                "$set": {
                    "title": title,
                    "contents": contains,
                }
            })
            flash("수정 되었습니다.")
            return redirect(url_for("board_view", idx=idx))
        else:
            flash("글 수정 권한이 없습니다.")
            return redirect(url_for("lists"))


@app.route("/delete/<idx>")
def board_delete(idx):
    return ""


if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True, port=9000)
 
 
 
 
 
------------------------------------------------------------------------------------------------
 
 
-join-
 
 
{% with messages = get_flashed_messages() %}
{% if messages %}
<script>
    alert('{{messages[-1]}}');
</script>
{% endif %}
{% endwith %}

<table>
    <form name="form" action="/join" method="POST">
        <thead>
            <caption>회원가입</caption>
        </thead>
        <tbody>
            <tr>
                <td>이름</td>
                <td><input type="text" name="name"></td>
            </tr>
            <tr>
                <td>이메일</td>
                <td><input type="text" nmae="email"></td>
            </tr>
            <tr>
                <td>비밀번호</td>
                <td><input type="password" name="pass"></td>
            </tr>
            <tr>
                <td>비밀번호 확인</td>
                <td><input type="password" name="pass2"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="가입하기"></td>
            </tr>
        </tbody>
    </form>
</table>
 
 
 
----------------------------------------------------------------------------------------------------------
 
-login-
 
{% with messages = get_flashed_messages() %} {% if messages %}
<script>
  alert("{{messages[-1]}}");
</script>
{% endif %} {% endwith %}

<table>
  <form name="form" action="/login" method="POST">
    {% if next_url %}
    <input type="hidden" name="next_url" value="{{next_url}}" />
    {% endif %}
    <thead>
      <caption>
        회원 로그인
      </caption>
    </thead>
    <tbody>
      <tr>
        <td>이메일</td>
        <td><input type="text" name="email" /></td>
      </tr>
      <tr>
        <td>비밀번호</td>
        <td><input type="password" name="pass" /></td>
      </tr>
      <tr>
        <td colspan="2"><input type="submit" value="로그인" /></td>
      </tr>
    </tbody>
  </form>
</table>
 
 
--------------------------------------------------------------------------------------------------------
 
 
- list -
 
 
{% with messages = get_flashed_messages() %}
{% if messages %}
<script>
    alert('{{messages[-1]}}');
</script>
{% endif %}
{% endwith %}

<script>
    function search() {
        var v_search = document.getElementById("search").value;
        var v_keyword = document.getElementById("keyword").value;

        if (v_search == "" || v_keyword == "") {
            return false;
        } else {
            self.location.href =
                "{{url_for('lists')}}?search=" + v_search + "&keyword=" + v_keyword;
        }
    }
</script>

{% if datas|length > 0 %}
<table>
    <thead>
        <tr>
            <td>번호</td>
            <td>제목</td>
            <td>이름</td>
            <td>날짜</td>
            <td>조회수</td>
        </tr>
    </thead>
    <tbody>
        <!--반복되는 구간-->
        <tr>
            {% for data in datas %}
            <td>{{loop.index + ((page - 1) * limit)}}</td>
            <td>
                <a
                    href="{{url_for('board_view', idx=data._id, page=page, search=search, keyword=keyword)}}">{{data.title}}</a>
            </td>
            <td>{{data.name}}</td>
            <td>{{data.pubdate|formatdatetime}}</td>
            <td>{{data.view}}</td>
        </tr>
        {% endfor %}
        <!--반복되는 구간 끝-->
    </tbody>
</table>

{% if block_start - 1 > 0 %}
<a href="{{url_for('lists', page=block_start - 1, search=search, keyword=keyword)}}">[이전]</a>
{% endif %} {% for i in range(block_start, block_last + 1) %} {% if i >
last_page_num %} {{ i }} {% else %} {% if i == page %}
<b>{{ i }}</b>
{% else %}
<a href="{{url_for('lists', page=i, search=search, keyword=keyword)}}">{{ i }}</a>
{% endif %} {% endif %} {% endfor %} {% if block_last < last_page_num %} <a
    href="{{url_for('lists', page=block_last + 1, search=search, keyword=keyword)}}">[다음]</a>
    {% endif %}

    <select name="search" id="search">
        <option value="" {% if search=='' or search==-1 %} selected {% endif %}>검색대상</option>
        <option value="0" {% if search==0 %} selected {% endif %}>제목</option>
        <option value="1" {% if search==1 %} selected {% endif %}>내용</option>
        <option value="2" {% if search==2 %} selected {% endif %}>제목+내용</option>
        <option value="3" {% if search==3 %} selected {% endif %}>작성자</option>
    </select>
    <input type="text" name="keyword" id="keyword" {% if keyword !="" %} value="{{keyword}}" {% endif %} />
    <input type="button" value="검색" onclick="search()" />

    {% else %}
    <h3>데이터가 없습니다.</h3>
    {% endif %}

    <a href="{{url_for('board_write')}}">글작성</a>
 
 
 
-------------------------------------------------------------------------------------------------------
 
 
 
- edit -
 
 
 
<html>

<body>
    <table>
        <form name="form" method="post" action="/edit/{{data._id}}">
            <tr>
                <td>작성자</td>
                <td><input type="text" name="name" value="{{session['name']}}" readonly /></td>
            </tr>
            <tr>
                <td>제목</td>
                <td><input type="text" name="title" /></td>
            </tr>
            <tr>
                <td>내용</td>
                <td><textarea type="text" name="contents">{{data.contents}}</textarea></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" /></td>
            </tr>
        </form>
    </table>
</body>

</html>
 
 
 
 

답변 1

답변을 작성해보세요.

0

그런문제는 프로그램의 흐름을 한번 먼저 생각해보시면 어디에서 문제가 생길지를 미리 예측해볼 수 있습니다.

회원가입을 했는데 이메일값에 문제가 있다면 회원 가입 폼, 회원가입 처리 함수, 이런식으로 프로그램의 흐름을 생각해보며 하나씩 원인을 분석해보는 습관을 들이시는게 좋습니다. 물론 첨부터 쉽지는 않습니다. 어쨌든 그런 순서로 올려주신 코드를 보니,

 

<td><input type="text" nmae="email"></td>

 

 

위와 같이 작성되어있는걸 봤습니다. nmae 이 아니라 name 입니다. 수정해서 한번 다시 해보시기 바랍니다.

 

문신호님의 프로필

문신호

질문자

2022.04.09

남박사님 친절하게 설명해주셔서 감사합니다!! 코드가 많아지니까 오타난거를 찾기가 어렵네요 ㅜ

하다가 모르는거나 궁금한 사항 있으면 질문드리겠습니다~ 감사합니다!

원래 제일 찾기 힘든게 오타 입니다. ㅋㅋ

제가 오타를 쉽게 찾은건 그만큼 오타로 고생을 많이 해봐서입니다.