강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

sbsys46님의 프로필 이미지
sbsys46

작성한 질문수

남박사의 파이썬으로 실전 웹사이트 만들기

join.html 의 form 태그값 을 member_join() 에서 처리못함.

해결된 질문

작성

·

74

0

join.html 내용 😀

{% with messages = get_flashed_messages() %}
    {% if messages %}
        <script>
            alert("{{messages[-1]}}")
        </script>
    {% endif %}
{% endwith %}

<html>
    <body>
        <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" name="email"></td>
                    </tr>
                    <tr>
                        <td>비밀번호</td>
                        <td><input type="password" name="pass1"></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>
    </body>
</html>

join 함수 부분 😀

@app.route("/join",methods=["GET","POST"])
def member_join():
    if request.method=="POST":
        name=request.args.get("name",type=str)
        email=request.args.get("email",type=str)
        pass1=request.args.get("pass1",type=str)
        pass2=request.args.get("pass2",type=str)
        
        print(name,email,pass1,pass2)
       
        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.now(timezone.utc).timestamp()*1000)
        post = {
            "name":name,
            "email":email,
            "pass":pass1,
            "joindate":current_utc_time,
            "logintime":"",
            "logincount":0
        }
        
        members.insert_one(post)
        
        return redirect(url_for("member_login"))
    else:
        return render_template("join.html")

입력화면 😀

image.png

실행결과 😀

message box

이미 등록된 메일주소 입니다. <= 매번 None 값으로 넘어오기 때문

None None None None

127.0.0.1 - - [14/Jul/2025 11:53:36] "POST /join HTTP/1.1" 200 -

질문:

  1. 값이 왜 전달되지 않았을까요.

  2.  

    type=str 로 했는데 None 값을 돌려 주었다면 join.html 의 입력값에 문제가 있을까요?

     

혼자서 몇차례고 분석해보았으나 해답을 못찾아 질문 올립니다.

답변 1

0

남박사님의 프로필 이미지
남박사
지식공유자

image.png

지금 올려주신 이미지를 봤을때 해당 값이 하나씩 실제 입력된 값이 아니라 브라우저에 저장된 값이 설정되어서 전송되는 상황 같습니다만..

만약 제 예상이 맞다면 이 경우에는 2가지 수정 방안이 있는데 첫째는 join.html 에서 <form>의 위치를 <table> 밖으로 이동해야 합니다. 현재 제가 강의에서 작성한 <form>의 위치는 디자인적 이유 때문에 그렇게 한건데, 원칙상으로는 잘못된 위치긴 합니다.

 

<form name="form" action="/join" method="POST">
  <table>
    <thead>
      <caption>회원가입</caption>
    </thead>
    <tbody>
      <tr>
        <td>이름</td>
        <td><input type="text" name="name"></td>
      </tr>
      <tr>
        <td>이메일</td>
        <td><input type="text" name="email"></td>
      </tr>
      <tr>
        <td>비밀번호</td>
        <td><input type="password" name="pass1"></td>
      </tr>
      <tr>
        <td>비밀번호확인 </td>
        <td><input type="password" name="pass2"></td>
      </tr>
      <tr>
        <td colspan="2"><input type="submit" value="가입하기"></td>
      </tr>        
    </tbody>
  </table>
</form>

그래서 위의 코드에서 처럼 수정합니다.

 

또 다른 방법은 <form>의 위치는 그대로 둔다면 각 <input> 요소에 해당 요소가 어느 폼에 속하는 요소인지를 명시적으로 작성합니다.

 <input type="text" name="name" form="joinForm">

위의 코드에서처럼 form="joinForm" 처럼 명시합니다.

 

참고해보시고 문제가 지속되면 다시 질문주시기 바랍니다.

sbsys46님의 프로필 이미지
sbsys46
질문자

마찬가지 결과 입니다.

그냥 form="joinForm" 만 추가로 삽입해보고 안되어서 form 명을 "joinForm" 으로 바꾸어서도 해보고 run.py 를 재실행해 보기도 하였으나 계속 None 값으로 넘오 옵니다.

sbsys46님의 프로필 이미지
sbsys46
질문자

죄송 합니다.

윗 부분을 못 보고 마지막 줄만보고 테스트한 결과 였습니다.

다시 시도 해보고 결과 올리겠습니다.

sbsys46님의 프로필 이미지
sbsys46
질문자

윗부분 결과도 마찬가지로 4가지 전달값이 모두 None 로 되네요.

원시적인 방법으로 write.html 을 복붙 하여 변형해가며 테스트 해보려 합니다.

시도후 다시 결과 올리겠습니다.

남박사님의 프로필 이미지
남박사
지식공유자

지금 다시 코드를 확인해보니

name = request.form.get("name", type=str)
email = request.form.get("email", type=str)
pass1 = request.form.get("pass1", type=str)
pass2 = request.form.get("pass2", type=str)

HTML에서 method가 POST 인데 파이썬에서 폼요소를 get으로 받고 있습니다.

 

if request.method == "POST":
    name = request.form.get("name", type=str)
    email = request.form.get("email", type=str)
    pass1 = request.form.get("pass1", type=str)
    pass2 = request.form.get("pass2", type=str)

POST인 경우 폼 요소를 위의 코드에서처럼 처리할 수 있게 수정해보세요.

 

sbsys46님의 프로필 이미지
sbsys46
질문자

    print(request.method)
    if request.method=="GET":
        name=request.args.get("name",type=str)
        email=request.args.get("email",type=str)
        pass1=request.args.get("pass1",type=str)
        pass2=request.args.get("pass2",type=str)
        
        print(name,email,pass1,pass2)

GET
None,None,None,None
       
       
print(request.method)
    if request.method=="GET":
        name=request.form.get("name",type=str)
        email=request.form.get("email",type=str)
        pass1=request.form.get("pass1",type=str)
        pass2=request.form.get("pass2",type=str)
        
        print(name,email,pass1,pass2)

GET
None,None,None,None

안되네요...

 

무엇이 문제인지 알수가 없네요.

남박사님의 프로필 이미지
남박사
지식공유자

image.png

지금 올려주신 내용을 보면 왜 그런지는 모르겠지만 request.method가 GET으로 넘어오고 있는거 같은데 실제 join.html 에서는 POST 형태로 전송되었어야 하는 사항으로 보입니다.

 

image.png

F12키를 눌러 브라우저의 개발자도구를 열고 Network 탭에서 join.html 입력 시 실제 가입처리가 POST로 가는지 위의 예시 이미지를 참고하여 GET으로 가는지부터 확인해보시기 바랍니다.(이미지는 그냥 예시일 뿐입니다.)

만약 GET으로 전송중이라면 join.html 코드를 모두 지우고 그냥 <form>과 <input>만 남기고 submit이 제대로 되는지부터 차근 차근 체크해봐야 할 듯 합니다.

 

정리하면 최초 GET 방식으로 넘어올땐 join.html 이 출력되어야 하고 join.html 에서 데이터를 전송했을때는 POST 형태로 전달되어야 합니다.

 

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

    print(f"method:: {request.method}")

    if request.method=="POST":
        name=request.args.get("name",type=str)
        email=request.args.get("email",type=str)
        pass1=request.args.get("pass1",type=str)
        pass2=request.args.get("pass2",type=str)

        print(f"arg.get >>> {name}, {email}, {pass1}, {pass2}")

        name=request.form.get("name",type=str)
        email=request.form.get("email",type=str)
        pass1=request.form.get("pass1",type=str)
        pass2=request.form.get("pass2",type=str)
        
        print(f"form.get >>> {name}, {email}, {pass1}, {pass2}")
       
        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.now(timezone.utc).timestamp()*1000)
        post = {
            "name":name,
            "email":email,
            "pass":pass1,
            "joindate":current_utc_time,
            "logintime":"",
            "logincount":0
        }
        
        members.insert_one(post)
        
        return redirect(url_for("member_login"))
    else:
        print("<< render_template join.html>>")

        return render_template("join.html")

일단 이렇게 구간구간 출력해보시기 바랍니다.

 

{% with messages = get_flashed_messages() %}
    {% if messages %}
        <script>
            alert("{{messages[-1]}}")
        </script>
    {% endif %}
{% endwith %}

<html>
    <body>
        <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" name="email"></td>
                    </tr>
                    <tr>
                        <td>비밀번호</td>
                        <td><input type="password" name="pass1"></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>

        <script>
        document.addEventListener("DOMContentLoaded", function() {
            const form = document.forms['form'];
            form.addEventListener('submit', function(event) {
                // 실제 전송은 잠깐 막음 (테스트용)
                event.preventDefault();

                const name = form.name.value;
                const email = form.email.value;
                const pass1 = form.pass1.value;
                const pass2 = form.pass2.value;

                // 콘솔 출력
                console.log("이름:", name);
                console.log("이메일:", email);
                console.log("비밀번호:", pass1);
                console.log("비밀번호 확인:", pass2);

                // 알림창 출력
                alert(
                  "이름: " + name + "\n" +
                  "이메일: " + email + "\n" +
                  "비밀번호: " + pass1 + "\n" +
                  "비밀번호 확인: " + pass2
                );

                // 테스트용이므로 여기선 막았는데, 실제 제출하려면 이 라인 주석 처리
                // form.submit();
            });
        });
        </script>
    </body>
</html>

그리고 html에서도 submit전 내용을 미리 위의 코드에서처럼 체크해보시는것도 도움될듯 합니다.

sbsys46님의 프로필 이미지
sbsys46
질문자

write.html을 복붙해서 단계적으로 수정해서 처리 했습니다.

무슨차이로 write.html 에서 넘긴건

request.method="POST" 되는데
수정전 join.html 에서는 "GET" 으로 받는지 이해가 안되는 군요.
물론 복붙한 수정본은 정상적으로 "POST" 받아져서 정상작동 합니다.

 

{% with messages = get_flashed_messages() %}
    {% if messages %}
        <script>
            alert("{{messages[-1]}}")
        </script>
    {% endif %}
{% endwith %}

<html>
    <body>
        <table>
            <form name="form" method="POST" action="/join">
          
            <tr>
                <td>작성자</td>
                <td><input type="text" name="name"></td>
            </tr>

            <tr>
                <td>이메일</td>
                <td><input type="text" name="email"></td>
            </tr>

            <tr>
                <td>비밀번호</td>
                <td><input type="password" name="pass1"></td>
            </tr>

            <tr>
                <td>비밀번호 확인</td>
                <td><input type="password" name="pass2"></td>
            </tr>

            <tr>
                <td colspan="2"><input type="submit" value="가입하기"></td>
            </tr>
 
            </form>
        </table>
       
    </body>
</html>
@app.route("/join",methods=["GET","POST"])
def member_join():

    print("join : ",request.method)
    if request.method=="POST":
        name=request.form.get("name",type=str)
        email=request.form.get("email",type=str)
        pass1=request.form.get("pass1",type=str)
        pass2=request.form.get("pass2",type=str)
        
        print("Para : ",name,email,pass1,pass2)
       
        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.now(timezone.utc).timestamp()*1000)
        post = {
            "name":name,
            "email":email,
            "pass":pass1,
            "joindate":current_utc_time,
            "logintime":"",
            "logincount":0
        }
        
        members.insert_one(post)
        
        return redirect(url_for("member_join"))
    else:
        return render_template("join.html")

join : POST

Para : sblee sbsys46@naver.com dpt dpt

127.0.0.1 - - [14/Jul/2025 15:56:45] "POST /join HTTP/1.1" 302 -

join : GET

127.0.0.1 - - [14/Jul/2025 15:56:45] "GET /join HTTP/1.1" 200 -

남박사님의 프로필 이미지
남박사
지식공유자

어쨌든 잘 처리 되셨으니 다행입니다. 그렇게 귀신에 홀린거 같이 왜 안되는지 모르겠는 상황이 있을 수 있습니다. 저도 그런 미스테리 경험이 아주 많습니다. 물론 더 깊게 이유를 찾다보면 원인이 찾아지긴 하지만 그 과정이 정신건강에 이롭지는 않습니다.

sbsys46님의 프로필 이미지
sbsys46

작성한 질문수

질문하기