묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결
🚨D-1🚨팀 "포춘 쿠키" 디자이너 모집 😊
팀 "포춘 쿠키" 디자이너 모집 😊🚨D-1🚨 🤗 UX/UI 디자이너를 모집합니다!! 🤗✨ 앱 UI/UX 디자인 경험을 쌓고 싶은데 어떻게 시작해야 할지 막막한 분✨ 본인의 UI/UX 디자인이 살아 움직이는 걸 보고 싶으신 분✨ 자신의 엄청난 디자인을 담아줄 그릇을 가진 개발자를 찾지 못하셨던 분🔥넘치는 열정🔥으로 도전해 볼 디자이너를 모집합니다!당장 지원하세요 🔥안녕하세요! 저희는 팀 “포춘쿠키” 입니다 :)🍀 프로젝트 내용저희 팀은 “LLM을 활용한 토론 보조 앱”이라는 주제로 ICT 한이음 공모전 예선을 합격하였고, 이를 디벨롭하여 앱 개발 및 배포까지 목표로 하고 있습니다.9월에 있을 1차 서류 심사를 위해, 8월까지 앱 개발 및 배포를 목표로 진행할 예정입니다.* ICT 멘토링 공모전 링크 : https://www.hanium.or.kr/portal/index.do🎮 팀 소개현재 저희 팀 “PortuneCookiess”는 숭실대학교 컴퓨터학부 3, 4학년 5명의 학우로 구성되어 있으며, 저희 팀은 다수의 개발 프로젝트 및 각종 공모전 수상 경력, 개발 외주 용역 경험을 가지고있는 실력 있는 개발자 5명으로 구성되어 있습니다. (프론트엔드 2명, 백엔드 2명, AI 1명)인원 모두 단순 프로젝트 경험이 아닌 절대적인 1위 수상을 바라보고 시작한 만큼 대학생 토이프로젝트 수준을 뛰어넘은 상용 애플리케이션 수준의 퀄리티를 약속드립니다.-팀원 개발 경력 中-2020 KDB 창업교육 미니 IR 대상 2020 서울시 SBA 종합 대상 2022 국방데이터 활용 경진대회 - 한국IT서비스산업협회 협회장상 2023 SW마에스트로 14기 수료📍 모집 파트디자인 파트 : UX/UI 앱 디자인, 앱 아이콘 디자인(❗ 프로젝트 경험은 없어도 되고 학생, 직장인, 취준생 상관 없이 가능합니다.)💰 지원 혜택- 피그마 강의 제공 (프로그래머스/유데미)- 상금 균등 분할- 대면 만남 시 교통비 및 회의실 제공- 유쾌한 팀원들과 함께 확실한 경험 및 경력 쌓기 가능 (쌉가능)👇🏻 지원 구글폼 (~5.17)https://forms.gle/vWMAPHpFxiqSdyPK9📌 참고 사항저희는 현재 대면회의로 진행되고 있습니다. 저희가 모두 숭실대학교 재학중이므로 서울 근교에서 회의 참여 가능하시면 좋을 것 같습니다.☎ Contact관련한 문의사항은 아래의 오픈채팅과 연락처로 편하게 연락 부탁드립니다!💬 카카오톡 오픈 채팅: https://open.kakao.com/o/sPEXIDrg
-
미해결
웹개발 진로에 대해서 질문드리고싶습니다.
안녕하세요? 저는 현재 웹개발 백엔드공부중인 컴공 졸업생입니다.인프런에서 스프링 강의를 수강하고 있습니다.제가 나이도 좀 있고 공백기도 있어서 고민이 있습니다.현재 제가 공부중인, 웹개발 스프링을 공부하면, 웹 개발 직종뿐만 아니라 다른 유사한 직종으로도 들어갈 수 있을까요?개발자 아무나 하는 것이 아니라는 말도 많이 들었고, 처음부터 웹 개발 회사 진입도 어렵다는 말을 많이 들었어서 고민이 됩니다.스프링 웹개발 분야를 공부했을 때, 개발직종말고 이와 유사한 직종 들어갈 수 있는 곳들도 있을까요?예를들면, 금융회사라든지 이런 부차적으로 개발을 하는 곳들로요.빨리 취업하는 것이 목표라서 질문드립니다. 감사합니다.
-
미해결
인프런 김영한 강사님 강의 듣고있는데 포트오류 생깁니다
Web server failed to start. Port 8080 was already in use. Identify and stop the process that's listening on port 8080 or configure this application to listen on another port. 이 문구들이 나오는데 김영한 강사님께서 이전 포트8080을 끄고 다음 것을 진행하라고 하셨습니다.그런데 애초에 중지버튼에 불이 들어와있지 않습니다.
-
미해결
컴퓨터공학과 진로에 대하여
컴퓨터 공학과 관련 분야에는 어떤 것들이 있나요?유튜브나 인터넷에 검색해보면 대부분 개발자가 많이 언급되는 것 같네요.웹 앱 개발자, ai 개발자, 데이터 분석가, 데이터 사이언티스트, 빅데이터 분석가, PM, 공기업 전산직 등이 있는 것 같네요. 혹시 위의 직업들 포함해서 신입이 도전가능할 비개발분야 추천가능하실까요?데이터분석가는 수학을 잘해야한다고 들었고 PM은 신입 거의 안뽑는다고 들었는데... 컴공 졸업생이 지원할 수 있는 비개발 분야는 없을까요..?
-
미해결
개발공부 다들 어떻게 시작하시나요?
개발공부 다들 어떻게 시작하시나요?
-
미해결JIRA를 활용해 더 효과적으로 프로젝트 협업하기
이슈에서 개발 필드가 안보여서 브랜치 접근이 안됩니다.
안보여서 깃헙 툴킷을 깔았는데 그래도 개발 필드와 브랜치가 안보이네요ㅠ
-
미해결
서울시뉴딜일자리_IT인턴 3개월 [급여월260만]지원사업안내_빅데이터 기반 서비스플랫폼 과정 [스터디,프로젝트,프론트엔드,백엔드,자바,코딩]
서울시에서 뉴딜일자리사업 일환으로 2차 서비스플랫폼개발자 양성과정으로 사전 교육 후 3개월 인턴십 (급여 월 260) 보내주는 프로그램 진행중인데 신청해보세요! 자세한 내용은 https://blog.naver.com/kjc_sh/222775806456 참고해주세요
-
미해결남박사의 파이썬으로 실전 웹사이트 만들기
글 작성 폼에 HTML 에디터 기능 추가하기 이미지 저장 오류..ㅠ
남박사님 계속 질문해서 죄송합니다..ㅠ 하다보니까 계속 오류가 나네요.... 이미지 업로드 관련해서 ajax 부분에서 오류가 나는것은 영상을 따라 하면서 해봐도 계속 같은 오류가 나와서 답답해서 질문드립니다. - 오류1 - 영상대로 수정하고 적용해서 똑같은 오류가 나오더라구요.. 그래서 이미지 업로드창 눌러서 해봤는데 비슷한 오류가 나옵니다. -오류2- -오류3- - 코드- -write.html- {% extends "main.html" %} {% block contents %} <script> $(document).ready(function() { $("#summernote").summernote({ height: 300, minHeight: null, maxHeight: null, lang: "ko-KR", popover: { image:[], link:[], air:[] }, callbacks: { onImageUpload: function(image) { for(var i = 0; i < image.length; i++) { uploadImage(image[i]); } } } }); }); function uploadImage(image) { var data = new FormData(); data.append("image", image); $.ajax({ url: "{{url_for('board.upload_image')}}", cache: false, contentType: false, processData: false, data: data, type:"post", success: function(url) { var image = $("<img>").attr("src",url).css('max-width', "900px"); $("#summernote").summernote("insertNode",image[0]); }, error: function(data) { console.log(data); alert(data); } }); } </script> <script> function checkForm() { if ($.trim($("#title").val()) == "") { alert("제목을 입력하세요"); $("#title").focus(); return false; } if ($.trim($("#summernote").val()) == "") { alert("내용을 입력하세요"); $("#summernote").focus(); return false; } } </script> <div style="padding: 50px 50px 50px 50px;"> <form name="form" method="post" action="{{url_for('board.board_write')}}" onsubmit="return checkForm()"> <div class="form-group"> <label for="name">작성자</label> <input class="form-control" id="name" type="text" name="name" value="{{session['name']}}" readonly> </div> <div class="form-group"> <label for="title">제목</label> <input class="form-control" type="text" name="title" id="title" placeholder="제목을 입력하세요"/> </div> <div class="form-group"> <label for="contents">내용</label> <textarea rows="8" class="form-control" type="text" name="contents" id="summernote" placeholder="내용을 입력하세요"></textarea> </div> <div class="text-center"><input class="btn btn-primary" type="submit" value="작성하기"></div> </form> </div> {% endblock %} --------------------------------------------------------------------------------------- -viev.html- {% extends "main.html" %} {% block contents %} <div style="padding: 50px 50px 50px 50px;"> <table class="table table-bordered"> <tbody> <tr> <td colspan="2">{{result.title}}</td> </tr> <tr> <td>{{result.name}}</td> <td class="text-right">{{result.pubdate|formatdatetime}}</td> </tr> <tr> <td colspan="2"><div style="min-height: 200px;"></div>{% autoescape false %}{{result.contents}}{% endautoescape %}</td> </tr> </tbody> </table> <a class="btn btn-primary" href="{{url_for('board.lists', page=page, search=search, keyword=keyword)}}">리스트</a> {% if session["id"] == result.writer_id %} <a class="btn btn-danger float-right ml-2" href="{{url_for('board.board_delete', idx=result.id)}}">글삭제</a> <a class="btn btn-warning float-right" href="{{url_for('board.board_edit', idx=result.id)}}">글수정</a> {% endif %} </div> {% endblock %} --------------------------------------------------------------------------------------------------- -main.html- <!DOCTYPE html> <html lang="kr"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{title}}</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.6.0.min.js" type="text/javascript"></script> <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script> <!-- include summernote css/js --> <link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.js"></script> <script> function validateEmail(email) { var pattern = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/; return pattern.test(email); } </script> {% with messages = get_flashed_messages() %} {% if messages %} <script> alert('{{messages[-1]}}'); </script> {% endif %} {% endwith %} </head> <body> <div class="containter"> {% include "menu.html" %} {% block contents %} {% endblock %} </div> </body> </html> -------------------------------------------------------------------------------------------------- -board.py- from main import * from flask import Blueprint, send_from_directory from flask import send_from_directory bluerprint = Blueprint("board", __name__, url_prefix="/board") @bluerprint.route("/upload_image", methods=["POST"]) def upload_image(): if request.method == "POST": file = request.files["image"] if file and allowed_file(file.filename): filename = "{}.jpg".format(rand_generator()) savefilepath = os.path.join(app.config["BOARD_IMAGE_PATH"], filename) file.save(savefilepath) return url_for("board.board_images", filename=filename) @bluerprint.route("/images/<filename>") def board_images(filename): return send_from_directory(app.config["BOARD_IMAGE_PATH"], filename) @bluerprint.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).sort("pubdate", -1) # 게시물의 총 갯수 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, title="게시판 리스트") @bluerprint.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, title="글 상세보기") return abort(404) @bluerprint.route("/write", methods=["GET", "POST"]) def board_write(): if session.get("id") is None: return redirect(url_for("member.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.board_view", idx=x.inserted_id)) else: return render_template("write.html", title="글 작성") @bluerprint.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 is None: flash("해당 게시물이 존재하지 않습니다.") return redirect(url_for("board.lists")) else: if session.get("id") == data.get("writer_id"): return render_template("edit.html", data=data, title="글 수정") else: flash("글 수정 권한이 없습니다.") return redirect(url_for("board.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.board_view", idx=idx)) else: flash("글 수정 권한이 없습니다.") return redirect(url_for("board.lists")) @bluerprint.route("/delete/<idx>") def board_delete(idx): board = mongo.db.board data = board.find_one({"_id": ObjectId(idx)}) if data.get("writer_id") == session.get("id"): board.delete_one({"_id": ObjectId(idx)}) flash("삭제 되었습니다.") else: flash("삭제 권한이 없습니다.") return redirect(url_for("board.lists")) --------------------------------------------------------------------------------- -__init__.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 datetime import datetime, timedelta from flask import abort from flask import redirect from flask import url_for from flask import flash from flask import session import math import time import os 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) BOARD_IMAGE_PATH = "C:\\python\\images" ALLOWED_EXTENSIONS =set(["txt", "pdf", "png", "jpg", "jpeg", "gif"]) app.config["BOARD_IMAGE_PATH"] = BOARD_IMAGE_PATH app.config["MAX-CONTENT_LENGTH"] = 15 * 1024 * 1024 if not os.path.exists(app.config["BOARD_IMAGE_PATH"]): os.mkdir(app.config["BOARD_IMAGE_PATH"]) # 아래의 파일들에서 main 의 app 에 접근을 해야하니 # 아래 import 위에 app 가 선언되어야 합니다. from .common import login_required, allowed_file, rand_generator from .filter import format_datetime # member, board 에서 login_required, format_datetime 을 사용하니까 # 당연히 member 와 board 가 위의 import 보다 먼저 나와선 안됩니다. from . import member from . import board app.register_blueprint(board.bluerprint) app.register_blueprint(member.bluerprint)
-
해결됨남박사의 파이썬으로 실전 웹사이트 만들기
(board_edit -> if data in None: 오류)오류나는 부분이 있어서 다시 질문 드립니다!
안녕하세요 남박사님! 저번에 질문 올렸는데요!.... 플라스크 프로젝트를 모듈화 하여 패키징 하기 부분에서 오류나서 질문을 드렸었습니다! 죄송합니다만 .... 댓글 달아주셨는데.. 제가 궁금한 부분도 다시 댓글 달았습니다. 답변 부탁드리겠습니다. 지금 진도는 javascript, iQuery 폼 검증 기능 추가하기 입니다. 모듈화 부분에서 전부 모듈화 하고... venv 들어가 있는 상태에서 재생버튼 눌러서 강제로 실행하니까.. 코드 오류 무시하고 실행이 되더라구요...! 왜그런지는 모르겠습니다! 실행이되서 진도를 나갔는데 다른 부분은 전부 정상적으로 적용되는데.. 한곳에서 적용이 안되는 구간이 있어서 질문 올립니다! -코드 오류 -1 - -코드 오류-2 - -글목록 수정- 글목록 작성한다음에 글수정 누르니까 오류가 나옵니다. -웹페이지 오류- -run.py- from main import app if __name__ == "__main__": app.run(host="0.0.0.0", debug=True, port=9000) ---------------------------------------------------------------------------------------------------- -__init__.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 datetime import datetime, timedelta from flask import abort from flask import redirect from flask import url_for from flask import flash from flask import session import math import time 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) # 아래의 파일들에서 main 의 app 에 접근을 해야하니 # 아래 import 위에 app 가 선언되어야 합니다. from .filter import format_datetime from .common import login_required # member, board 에서 login_required, format_datetime 을 사용하니까 # 당연히 member 와 board 가 위의 import 보다 먼저 나와선 안됩니다. from . import member from . import board app.register_blueprint(board.bluerprint) app.register_blueprint(member.bluerprint) -------------------------------------------------------------------------------------------- -board.py- from turtle import title from main import * from flask import Blueprint bluerprint = Blueprint("board", __name__, url_prefix="/board") @bluerprint.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).sort("pubdate", -1) # 게시물의 총 갯수 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, title="게시판 리스트") @bluerprint.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, title="글 상세보기") return abort(404) @bluerprint.route("/write", methods=["GET", "POST"]) def board_write(): if session.get("id") is None: return redirect(url_for("member.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.board_view", idx=x.inserted_id)) else: return render_template("write.html", title="글 작성") @bluerprint.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("board.lists")) else: if session.get("id") == data.get("writer_id"): return render_template("edit.html", data=data, title="글 수정") else: flash("글 수정 권한이 없습니다.") return redirect(url_for("board.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.board_view", idx=idx)) else: flash("글 수정 권한이 없습니다.") return redirect(url_for("board.lists")) @bluerprint.route("/delete/<idx>") def board_delete(idx): board = mongo.db.board data = board.find_one({"_id": ObjectId(idx)}) if data.get("writer_id") == session.get("id"): board.delete_one({"_id": ObjectId(idx)}) flash("삭제 되었습니다.") else: flash("삭제 권한이 없습니다.") return redirect(url_for("board.lists")) --------------------------------------------------------------------------------- -member.py- from turtle import title from main import * from flask import Blueprint bluerprint = Blueprint("member", __name__, url_prefix="/member") @bluerprint.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", title="회원가입") if pass1 != pass2: flash("비밀번호가 일치하지 않습니다.") return render_template("join.html", title="회원가입") members = mongo.db.members cnt = members.count_documents({"email": email}) if cnt > 0: flash("중복된 이메일 주소입니다.") return render_template("join.html", title="회원가입") 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 redirect(url_for("member.member_login")) else: return render_template("join.html", title="회원가입") @bluerprint.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.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("board.lists")) return redirect(url_for("board.lists")) else: flash("비밀번호가 일치하지 않습니다.") return redirect(url_for("member.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, title="회원로그인") else: return render_template("login.html", title="회원로그인") @bluerprint.route("/logout") def member_logout(): try: del session["name"] del session["id"] del session["email"] except: pass return redirect(url_for('member.member_login')) ---------------------------------------------------------------------------------- -main.html- <!DOCTYPE html> <html lang="kr"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{title}}</title> {% with messages = get_flashed_messages() %} {% if messages %} <script> alert('{{messages[-1]}}'); </script> {% endif %} {% endwith %} </head> <body> {% include "menu.html" %} {% block contents %} {% endblock %} </body> </html> --------------------------------------------------------------------------- -edit.html- {% extends "main.html" %} {% block contents %} <table> <form name="form" method="post" action="{{url_for('board.board_edit', idx=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> {% endblock %} ------------------------------------------------------------------------- -join.html- {% extends "main.html" %} {% block contents %} <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="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> {% endblock %} ------------------------------------------------------------------------------- -list.html- {% extends "main.html" %} {% block contents %} <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('board.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.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('board.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('board.lists', page=i, search=search, keyword=keyword)}}">{{ i }}</a> {% endif %} {% endif %} {% endfor %} {% if block_last < last_page_num %} <a href="{{url_for('board.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.board_write')}}">글작성</a> {% endblock %} -------------------------------------------------- -login.html- {% extends "main.html" %} {% block contents %} <table> <form name="form" action="{{url_for('member.member_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> {% endblock %} ---------------------------------------------- -view.html- {% extends "main.html" %} {% block contents %} {% with messages = get_flashed_messages() %} {% if messages %} <script> alert("{{messages[-1]}}"); </script> {% endif %} {% endwith %} {{result.title}} <br /> {{result.name}} <br /> {{result.pubdate|formatdatetime}} <br /> {{result.view}} <br /> {{result.contents}} <br /> <a href="{{url_for('board.lists', page=page, search=search, keyword=keyword)}}" >리스트</a > {% if session["id"] == result.writer_id %} <a href="{{url_for('board.board_delete', idx=result.id)}}">글삭제</a> <a href="{{url_for('board.board_edit', idx=result.id)}}">글수정</a> {% endif %} {% endblock %} ------------------------- -write.html- {% extends "main.html" %} {% block contents %} <table> <form name="form" method="post" action="{{url_for('board.board_write')}}"> <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"></textarea></td> </tr> <tr> <td colspan="2"><input type="submit" /></td> </tr> </form> </table> {% endblock %}
-
미해결최신 SwiftUI와 UIKit과 함께하는 올인원 iOS 앱 개발 강의
Windows에서도 수업 내용 실습을 무리 없이 진행 가능한가요?`
맥북을 가지고 있지 않은데 ios 개발을 해보고 싶어서 강의를 결제했습니다. Window에서도 강의 실습이 가능한가요?