powerstone 2022. 3. 24. 19:50
728x90

[1] 개요

  1. URL

    - HOST/register

 

  2. 구성

    - 아이디 입력창 (현재 아이디 중복 체크 기능X)

    - 비밀번호 입력창

    - 비밀번호확인 입력창 (현재 비밀번호 확인 기능X)

    - 이름 입력창

    - 생년월일 입력창

    - 성별 선택 라디오버튼

    - 이메일 입력창 (현재 이메일 중복 체크 기능X)

    - 주소 찾기 버튼 및 상세주소 입력창

    - 휴대폰번호 입력창 (현재 휴대폰번호 중복 체크 기능X)

    - 프로필 사진 파일 선택 버튼

    - 일반회원/점주 선택 라디오버튼

    - 이상 필수입력 사항

    - 회원가입 버튼

    - 점주 선택 시

      - 사업자등록번호 입력창(필수)

      - 식당이름 입력창(필수)

      - 점주이름 입력창(필수)

      - 주소 찾기 버튼 및 상세주소 입력창(필수)

      - 음식점정보 입력창

      - 음식점 연락처 입력창

      - 영업시간 입력창

      - 재료준비시간 입력창

      - 음식점사진 파일 선택 버튼

      - 업종 선택 콤보박스

[2] CODE

  1. HTML

/templates/register.html

<section class="p-5">
    <div class="m-5" style="position:absolute; left:50%; transform:translateX(-50%); width:35%;">
        <header class="container p-3" style="text-align:center; width:100%;">
            <h3 style="white-space:nowrap;">회원가입</h3>
        </header>
        <form name="regist" action="registerimpl" method="post" id="register_box" enctype="multipart/form-data" style="text-align:left;">
            {% csrf_token %}
            <div class="input-box">
                <input id="custid" type="text" name="custid" placeholder="아이디" autocomplete="off" required>
                <label for="custid">아이디</label>
            </div>
            <div class="input-box">
                <input id="custpw" type="password" name="custpw" placeholder="비밀번호" onchange="check_pw()" required>
                <label for="custpw">비밀번호</label>
            </div>
            <div class="input-box">
                <input id="custpwcheck" type="password" name="pwcheck" placeholder="비밀번호확인" onchange="check_pw()" required>
                <label for="custpwcheck">비밀번호확인</label>
            </div>
            <div class="input-box">
                <input id="custname" type="text" name="custname" placeholder="이름" autocomplete="off" required>
                <label for="custname">이름</label>
            </div>
            <div class="input-box">
                <input id="custbday" type="date" name="birth" placeholder="생년월일" autocomplete="off" required>
                <label for="custbday">생년월일</label>
            </div>
            <div>
                <div class="box-radio-input">
                    <input id="man" type="radio" name="gender" value="남" style="width:15px; height:15px;" required>
                    <span>남자</span>
                    <input id="woman" type="radio" name="gender" value="여" style="width:15px; height:15px;" required>
                    <span>여자</span>
                </div>
            </div>
            <div class="input-box">
                <input id="custemail" type="text" name="custemail" placeholder="이메일" autocomplete="off" required>
                <label for="custemail">email</label>
            </div>
            <div class="input-box">
                <div class="formfield m-1" id="custaddr">
                    <input type="text" id="sample4_postcode" placeholder="우편번호" required>
                    <input type="button" onclick="sample4_execDaumPostcode()" value="주소 찾기" style="border:1px solid grey; border-radius:3px;">
                    <br>
                    <input type="text" id="sample4_roadAddress" name="address1" placeholder="도로명주소" style="width:40%" required>
                    <input type="text" id="sample4_jibunAddress" placeholder="지번주소" style="width:40%" required>
                    <br>
                    <span id="guide" style="color:#999;display:none"></span>
                    <span>상세주소</span>
                    <input type="text" id="sample4_detailAddress" name="address2" placeholder="상세주소" style="width:30%" required>

                    <input type="text" id="sample4_extraAddress" placeholder="참고항목" style="width:30%" required>

                    <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
                    <script>
                        //본 예제에서는 도로명 주소 표기 방식에 대한 법령에 따라, 내려오는 데이터를 조합하여 올바른 주소를 구성하는 방법을 설명합니다.
                        function sample4_execDaumPostcode() {
                            new daum.Postcode({
                                oncomplete: function(data) {
                                    // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                                    // 도로명 주소의 노출 규칙에 따라 주소를 표시한다.
                                    // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                                    var roadAddr = data.roadAddress; // 도로명 주소 변수
                                    var extraRoadAddr = ''; // 참고 항목 변수

                                    // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                                    // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                                    if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                                        extraRoadAddr += data.bname;
                                    }
                                    // 건물명이 있고, 공동주택일 경우 추가한다.
                                    if(data.buildingName !== '' && data.apartment === 'Y'){
                                       extraRoadAddr += (extraRoadAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                                    }
                                    // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                                    if(extraRoadAddr !== ''){
                                        extraRoadAddr = ' (' + extraRoadAddr + ')';
                                    }

                                    // 우편번호와 주소 정보를 해당 필드에 넣는다.
                                    document.getElementById('sample4_postcode').value = data.zonecode;
                                    document.getElementById("sample4_roadAddress").value = roadAddr;
                                    document.getElementById("sample4_jibunAddress").value = data.jibunAddress;

                                    // 참고항목 문자열이 있을 경우 해당 필드에 넣는다.
                                    if(roadAddr !== ''){
                                        document.getElementById("sample4_extraAddress").value = extraRoadAddr;
                                    } else {
                                        document.getElementById("sample4_extraAddress").value = '';
                                    }

                                    var guideTextBox = document.getElementById("guide");
                                    // 사용자가 '선택 안함'을 클릭한 경우, 예상 주소라는 표시를 해준다.
                                    if(data.autoRoadAddress) {
                                        var expRoadAddr = data.autoRoadAddress + extraRoadAddr;
                                        guideTextBox.innerHTML = '(예상 도로명 주소 : ' + expRoadAddr + ')';
                                        guideTextBox.style.display = 'block';

                                    } else if(data.autoJibunAddress) {
                                        var expJibunAddr = data.autoJibunAddress;
                                        guideTextBox.innerHTML = '(예상 지번 주소 : ' + expJibunAddr + ')';
                                        guideTextBox.style.display = 'block';
                                    } else {
                                        guideTextBox.innerHTML = '';
                                        guideTextBox.style.display = 'none';
                                    }
                                }
                            }).open();
                        }
                    </script>
                </div>
                <div class="input-box">
                    <input id="custphone" type="tel" name="custphone" placeholder="휴대폰번호" autocomplete="off" required>
                    <label for="custphone">휴대폰번호</label>
                </div>
                <div class="input-box" style="padding-top:8px;">
                    <span style="font-size:15px;">프로필사진
                    <input type="file" id="custimg" name="custimg" accept="image/*"></span>
                </div>
                <div>
                    <div class="box-radio-input">
                        <input id="cust" type="radio" name="host_flag" value="0" onclick="div_OnOff(this.value,'con');" style="width:15px; height:15px;" required>
                        <span>일반회원</span>
                        <input id="ceo" type="radio" name="host_flag" value="1" onclick="div_OnOff(this.value,'con');" style="width:15px; height:15px;" required>
                        <span>점주</span>
                        <script>
                            function div_OnOff(v,id){
                                // 라디오 버튼 value 값 조건 비교
                                    if(v == "1"){
                                        document.getElementById(id).style.display = ""; // 보여줌
                                        list = document.getElementsByClassName('con_input');
                                        for (var i = 0; i < list.length; i++){
                                            list[i].setAttribute("required", "");// 점주용 필드값 required 로 변경
                                        }
                                    }else{
                                        document.getElementById(id).style.display = "none"; // 숨김
                                        list = document.getElementsByClassName('con_input');
                                        for (var i = 0; i < list.length; i++){
                                            list[i].removeAttribute("required");// 점주용 필드값 required 제거
                                        }
                                }
                            }
                        </script>
                        <div id="con" style="display:none">
                            점주용 필드
                            <div class="input-box">
                                <input id="reg_num" class="con_input" type="text" name="reg_num" placeholder="식당이름" autocomplete="off" minlength="10" maxlength="10">
                                <label for="reg_num">사업자등록번호</label>
                            </div>
                            <div class="input-box">
                                <input id="rest_name" class="con_input" type="text" name="rest_name" placeholder="식당이름" autocomplete="off">
                                <label for="rest_name">식당이름</label>
                            </div>
                            <div class="input-box">
                                <input id="host_name" class="con_input" type="text" name="host_name" placeholder="점주이름" autocomplete="off">
                                <label for="host_name">점주이름</label>
                            </div>
                            <div class="input-box">
                                <div class="formfield m-1" id="hostaddr">
                                    <input type="text" id="sample4_hpostcode" class="con_input" placeholder="우편번호">
                                    <input type="button" onclick="sample4_hexecDaumPostcode()" value="주소 찾기" style="border:1px solid grey; border-radius:3px;">
                                    <br>
                                    <input type="text" id="sample4_hroadAddress" class="con_input" name="address3" placeholder="도로명주소" style="width:40%">
                                    <input type="text" id="sample4_hjibunAddress" class="con_input" placeholder="지번주소" style="width:40%">
                                    <br>
                                    <span id="hguide" style="color:#999;display:none"></span>
                                    <span>상세주소</span>
                                    <input type="text" id="sample4_hdetailAddress" class="con_input" name="address4" placeholder="상세주소" style="width:30%">

                                    <input type="text" id="sample4_hextraAddress" class="con_input" placeholder="참고항목" style="width:30%">
                                </div>
                                <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
                                <script>
                                    //본 예제에서는 도로명 주소 표기 방식에 대한 법령에 따라, 내려오는 데이터를 조합하여 올바른 주소를 구성하는 방법을 설명합니다.
                                    function sample4_hexecDaumPostcode() {
                                        new daum.Postcode({
                                            oncomplete: function(data) {
                                                // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                                                // 도로명 주소의 노출 규칙에 따라 주소를 표시한다.
                                                // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                                                var roadAddr = data.roadAddress; // 도로명 주소 변수
                                                var extraRoadAddr = ''; // 참고 항목 변수

                                                // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                                                // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                                                if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                                                    extraRoadAddr += data.bname;
                                                }
                                                // 건물명이 있고, 공동주택일 경우 추가한다.
                                                if(data.buildingName !== '' && data.apartment === 'Y'){
                                                   extraRoadAddr += (extraRoadAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                                                }
                                                // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                                                if(extraRoadAddr !== ''){
                                                    extraRoadAddr = ' (' + extraRoadAddr + ')';
                                                }

                                                // 우편번호와 주소 정보를 해당 필드에 넣는다.
                                                document.getElementById('sample4_hpostcode').value = data.zonecode;
                                                document.getElementById("sample4_hroadAddress").value = roadAddr;
                                                document.getElementById("sample4_hjibunAddress").value = data.jibunAddress;

                                                // 참고항목 문자열이 있을 경우 해당 필드에 넣는다.
                                                if(roadAddr !== ''){
                                                    document.getElementById("sample4_hextraAddress").value = extraRoadAddr;
                                                } else {
                                                    document.getElementById("sample4_hextraAddress").value = '';
                                                }

                                                var hguideTextBox = document.getElementById("hguide");
                                                // 사용자가 '선택 안함'을 클릭한 경우, 예상 주소라는 표시를 해준다.
                                                if(data.autoRoadAddress) {
                                                    var expRoadAddr = data.autoRoadAddress + extraRoadAddr;
                                                    hguideTextBox.innerHTML = '(예상 도로명 주소 : ' + expRoadAddr + ')';
                                                    hguideTextBox.style.display = 'block';

                                                } else if(data.autoJibunAddress) {
                                                    var expJibunAddr = data.autoJibunAddress;
                                                    hguideTextBox.innerHTML = '(예상 지번 주소 : ' + expJibunAddr + ')';
                                                    hguideTextBox.style.display = 'block';
                                                } else {
                                                    hguideTextBox.innerHTML = '';
                                                    hguideTextBox.style.display = 'none';
                                                }
                                            }
                                        }).open();
                                    }
                                </script>
                            </div>
                            <div class="input-box">
                                <input id="restindex" type="text" name="restindex" placeholder="음식점정보" autocomplete="off">
                                <label for="restindex">음식점정보</label>
                            </div>
                            <div class="input-box">
                                <input id="hostphone" type="text" name="hostphone" placeholder="음식점연락처" autocomplete="off">
                                <label for="hostphone">음식점연락처</label>
                            </div>
                            <div class="input-box">
                                <input id="openhour" type="text" name="openhour" placeholder="영업시간" autocomplete="off">
                                <label for="openhour">영업시간</label>
                            </div>
                            <div class="input-box">
                                <input id="breakhour" type="text" name="breakhour" placeholder="휴식시간" autocomplete="off">
                                <label for="breakhour">재료준비시간</label>
                            </div>
                            <div class="input-box" style="padding-top:8px;">
                                <span>음식점사진
                                <input type="file" id="restimg" name="restimg" accept="image/* "></span>
                            </div>
                            <div class="input-box">
                                <span>업종을선택하세요</span>
                                <select id="cate_id" name="cate_id" required>
                                    <option value="">선택</option>
                                    <option value="10">한식</option>
                                    <option value="20">분식</option>
                                    <option value="30">디저트</option>
                                    <option value="40">일식</option>
                                    <option value="50">치킨</option>
                                    <option value="60">피자</option>
                                    <option value="70">아시안</option>
                                    <option value="80">양식</option>
                                    <option value="90">중식</option>
                                    <option value="100">패스트푸드</option>
                                </select>
                            </div>

                        </div>
                    </div>
                </div>
                <br>
                <div class="btnfield" style="text-align:center">
                    <input type="submit" value="회원가입" style="width:80%">
                </div>
            <br>
            <br>
            <br>
            </div>
        </form>
    </div>
</section>

  2. CSS

    - /static/css/styles.css

 

  3. JavaScript

    - HTML 에 포함

    - 주소 검색 API

    - 일반회원/점주 라디오버튼 클릭에 따른 점주용 필드 화면 출력 결정

 

  4. Application

    1) register( ) 

      - 회원가입 화면으로 이동

    2) registerimpl( )

      - /registerimpl 을 요청하여 회원가입 화면에서 입력된 정보를 POST 방식으로 받아서 처리

      - 점주로 가입하는 경우(host_flag==1), 해당 정보 별도 테이블에 저장

      - 회원가입 완료되면, id 정보를 request.session에 저장하여, 자동으로 로그인 되도록 구현

      - 현재 회원가입 버튼 클릭 후, 입력된 정보에 따라서 오류가 나는 경우, 예외처리가 되어있지 않음

@request_mapping("")
class MyView(View):

    @request_mapping("/register", method="get")
    def register(self, request):
        return render(request, 'register.html');

    @request_mapping("/registerimpl", method="post")
    def registerimpl(self, request):
        host_flag = int(request.POST['host_flag']);
        id = request.POST['custid'];
        pwd = request.POST['custpw'];
        name = request.POST['custname'];
        birth = request.POST['birth'];
        gender = request.POST['gender'];
        email = request.POST['custemail'];
        address1 = request.POST['address1'];
        address2 = request.POST['address2'];
        phone = request.POST['custphone'];
        imgname = '';
        if 'custimg' in request.FILES:
            img = request.FILES['custimg'];
            imgname = img._name;
            f = open('%s/%s' % (UPLOAD_DIR, imgname), 'wb')
            for chunk in img.chunks():
                f.write(chunk);
                f.close();
        profile = Cust(id=id, pwd=pwd, name=name, birth=birth, gender=gender, email=email,
                       address=address1 + address2,
                       phone=phone, host_flag=host_flag, custimg=imgname);
        profile.save();

        if host_flag==1:
            reg_num = request.POST['reg_num'];
            rest_name = request.POST['rest_name'];
            host_name = request.POST['host_name'];
            address3 = request.POST['address3'];
            address4 = request.POST['address4'];
            restindex = request.POST['restindex'];
            hostphone = request.POST['hostphone'];
            openhour = request.POST['openhour'];
            breakhour = request.POST['breakhour'];
            cate_id = request.POST['cate_id']
            imgname2 = '';

            if 'restimg' in request.FILES:
                img = request.FILES['restimg'];
                imgname2 = img._name;
                f = open('%s/%s' % (UPLOAD_DIR, imgname2), 'wb')
                for chunk in img.chunks():
                    f.write(chunk);
                    f.close();
            restprf = Rest(cust=profile, reg_num=reg_num, rest_name=rest_name, host_name=host_name, address=address3 + address4,
                            restindex=restindex, phone=hostphone, openhour=openhour, breakhour=breakhour, cate_id=cate_id, restimg=imgname2);
            restprf.save();

        # 회원가입 완료 시, 자동 로그인
        request.session['sessionid'] = profile.id
        request.session['sessionname'] = profile.name
        request.session['sessionimg'] = profile.custimg

        return redirect('/')

- 끝 -

728x90