묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨남박사의 파이썬으로 실전 웹사이트 만들기
(게시판 댓글구현 오류) count 부분에서 오류가 나는데.. 어떻게 해야할까요..ㅠ?
안녕하세요 남박사님 남박사님 덕분에 강의를 잘듣고 진도를 나가고 있습니다. 이해가 안가는 부분도 아직 있지만 열심히 배울려고 노력하고 있는데요! 이번 댓글기능 만들기 부분에서 오류나는 부분있어서 질문올립니다. 댓글기능 구연하고 마지막 부분에서 jinja2.exceptions.UndefinedError: 'pymongo.cursor.Cursor object' has no attribute 'count'라고 오류가 나는데.. 저번에 {% if comments.count() > 0 %} 이부분이 몽고db 부분하고 연동이 안되는거 같아서 버전 차이라고 하셔서 count_documents({조건})로 변경해봤는데.. 오류는 나더라구요..! - 오류 - -코드 - -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") def board_delete_attach_file(filename): abs_path = os.path.join(app.config["BOARD_ATTACH_FILE_PATH"], filename) if os.path.exists(abs_path): os.remove(abs_path) return True return False @bluerprint.route("/comment_write", methods=["POST"]) @login_required def comment_write(): if request.method == "POST": print("POST OK") name = session.get("name") writer_id = session.get("id") root_idx = request.form.get("root_idx") comment = request.form.get("comment") current_utc_time = round(datetime.utcnow().timestamp() * 1000) c_comment = mongo.db.comment post = { "root_idx": str(root_idx), "writer_id": writer_id, "name": name, "comment": comment, "pubdate": current_utc_time } print(post) c_comment.insert_one(post) return redirect(url_for("board.board_view", idx=root_idx)) @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("/files/<filename>") def board_files(filename): return send_from_directory(app.config["BOARD_ATTACH_FILE_PATH"], filename, as_attachment=True) @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", ""), "attachfile": data.get("attachfile", "") } comment = mongo.db.comment comments = comment.find({"root.idx": str(data.get("_id"))}) return render_template("view.html", result=result, comments=comments, page=page, search=search, keyword=keyword, title="글 상세보기") return abort(404) @bluerprint.route("/write", methods=["GET", "POST"]) def board_write(): if request.method == "POST": filename = None if "attachfile" in request.files: file = request.files["attachfile"] if file and allowed_file(file.filename): filename = check_filename(file.filename) file.save(os.path.join(app.config['BOARD_ATTACH_FILE_PATH'], filename)) name = request.form.get("name") title = request.form.get("title") contents = request.form.get("contents") request.files 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, } if filename is not None: post["attachfile"] = filename 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") deleteoldfile = request.form.get("deleteoldfile", "") board = mongo.db.board data = board.find_one({"_id": ObjectId(idx)}) if session.get("id") == data.get("writer_id"): filename = None if "attachfile" in request.files: file = request.files["attachfile"] if file and allowed_file(file.filename): filename = check_filename(file.filename) file.save(os.path.join(app.config["BOARD_ATTACH_FILE_PATH"], filename)) if data.get("attachfile"): board_delete_attach_file(data.get("attachfile")) else: if deleteoldfile == "on": filename = None if data.get("attachfile"): board_delete_attach_file(data.get("attachfile")) else: filename = data.get("attachfile") board.update_one({"_id": ObjectId(idx)}, { "$set": { "title": title, "contents": contains, "attachfile": filename } }) 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")) ------------------------------------------------------------------------------------------------------- - view.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> {% if result.attachfile %} <tr> <td>첨부파일</td> <td><a href="{{url_for('board.board_files', filename=result.attachfile)}}">{{result.attachfile}}</a></td> </tr> {% endif %} <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 %} <br> <br> <form id="commentForm" name="commentForm" action="{{url_for('board.comment_write')}}" method="POST"> <input type="hidden" name="csrf_token" value="{{csrf_token()}}"> <input type="hidden" name="root_idx" value="{{result.id}}"> <div> <span><strong>댓글</strong></span> <span id="cCnt"></span> <table class="table"> <tr> <td><textarea rows="3" cols="110" id="comment" name="comment" placeholder="댓글을 입력하세요"></textarea></td> <td><input type="submit" class="btn btn-success" style="height: 80px;" value="등록하기"></td> </tr> </table> </div> </form> {% if comments.count() > 0 %} {% for c in comments %} <div> <table class="table"> <tr> <td width="100"><h6>{{c.name}}</h6></td> <td>{{c.comment}}</td> <td class="text-right" width="200">{{c.pubdate | formatdatetime}}</td> </tr> </table> </div> {% endfor %} {% endif %} </div> {% endblock %}
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part3: 자료구조와 알고리즘
피벗의 위치 질문드립니다.
피벗의 위치를 제일 처음으로 하시는 이유가 있을까요? 최우측이나, 향상된 pivot을 위해서는 왼, 오, 중간 값중에서 중앙값을 해야한다는 글이 있어서 질문드립니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
./store/configureStore.js파일에서 'redux' 최신 버전 질문입니다.
현재 redux가 4.2.0(최신)을 설치한 상태라서 createStore를 사용하려고 하면 createStore대신 @redux/toolkit의 configureStore함수를 사용하라고 권고하는 메시지를 읽었어요. 그래서 reduxjs/toolkit(1.8.1)에서 configureStore을 가져와서 createStore대신에 configureStore를 사용했는데(@redux/toolkit 공식문서에 나와있는대로 reducer, middleware, devTools, enhancers를 매개변수로 넣어주었습니다.), redux를 사용할때(회원가입 버튼을 누를 때) 이렇게 에러가 떠서 질문드립니다.(물론 createStore를 사용하면 잘 작동하기는 하는데 configureStore를 사용하면 잘 안되서 어떻게 하면 에러를 해결할 수 있을까해서 질문드립니다.) 첫번째 사진은 configureStore코드이고, 두번째 사진은 에러 메시지 입니다.
-
미해결스프링부트 시큐리티 & JWT 강의
postman으로 요청해도 아무런 반응이 없습니다.
스프링 시큐리티가 제공하는 url을 제외하고 컨트롤러에 명시된 /home /token /join 모두 무반응인데 이 경우 어떤 설정이 잘못된건지 알 수 있을까요?
-
해결됨스프링 시큐리티
안녕하세요. 강사님 문의드릴게 있습니다.
안녕하세요 강사님. 완강 후 현재 2회차 수강중에 있습니다. 몇 가지 여쭤볼게 있어서 이렇게 문의드립니다. 제가 공부한 내용을 정리하는 개인 블로그가 있는데 출처를 남기고 강사님의 강의 내용을 토대로 공부한 내용을 정리해서 포스팅해도 괜찮을까요? 혹시 괜찮으시다면 강의때 사용하셨던 ppt 의 이미지 같은 부분들을 인용해서 정리해도 괜찮으실까요? 출처는 반드시 남기겠습니다! 좋은 강의 감사드립니다.
-
미해결리눅스 쉘 스크립트
혹시 해당 강의에 대한 문서는 없나요?
학습후 반복적으로 자료를 보고싶은데 혹시 강의에 사용하고계신 문서는 제공해주실 수 없으신가요?ㅠ
-
미해결[R을 R려줘] R 기초다지기
R 사용중 자동완성이 안됩니다 ㅠㅠ
안녕하세요! 윈도우즈 R 설치후 함수 사용중에 Tab키를 눌러도 자동완성이 안됩니다.ㅠㅠ 이경우 어떻게 해결할 수 있을까요? 열정적이고 쉬운 강의 늘 감사드립니다!!
-
미해결일잘하는 마케터, MD에게 꼭 필요한 파이썬 데이터 분석
5강 웹크롤링
- 5강 7분경에 네이버 쇼핑몰 크롤링 하면 리뷰가 나오는데 실제 카피해서 돌려보면 페이지 1 2 3 4 이렇게만 나오는건 왜 그런건가요? 강의대로 리뷰 내용을 보려면 어떻게 해야 하나요 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
미해결만들면서 배우는 리액트 : 기초
Failed to load resource
콘솔에서 이 오류를 어떻게 해결하는 건지 모르겠습니다 원래는 고양이 사진이 잘 나왔었는데 지금은 나오지 않아요
-
미해결만들면서 배우는 리액트 : 기초
if (favorite.length == 0) 이 때 =가 2개인가요 3개인가요?
안녕하세요 유림님 강의 들으면서 따라치고 있는데 = 표시가 2개인지 3개인지 모르겠습니다
-
미해결플러터와 장고로 1시간만에 퀴즈 앱/서버 만들기 [무작정 풀스택]
Quiz.fromMap 작성이유가 궁금합니다.
작성하는 이유가 궁금합니다.
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
업로드페이지만들기 강좌에서요 회원가입하고 로그인하라고 하셔서 했는데요
업로드페이지만들기 강좌에서요 회원가입하고 로그인하라고 하셔서 했는데요 [HPM] Error occurred while trying to proxy request /api/users/login from localhost:3000 to http://localhost:5000 (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors) 회원가입하고 로그인하니까 계속 이런 오류가 나서요 해결 방법 좀 알려주실수 있을까요? 보니까 회원가입 자체가 안되는거 같아서요
-
미해결예제로 배우는 딥러닝 자연어 처리 입문 NLP with TensorFlow - RNN부터 BERT까지
네이버 영화리뷰 파인튜닝 질문드려요
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 앞선 과정에서 한글이든 영어든 토크나이저로 토큰화 시킨 후에 모델에 입력값으로 넣어야 하는 것으로 이해했습니다. 그런데, bert 모델에 넣을때는 토큰화 하지 않는 것 같은데 토큰화를 안해주는 이유가 있나요? 아니면 제가 토큰화하는 코드를 못본걸까요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
DTO를 반환에서만 사용하면 안되나요?
다음과같이 컨트롤러로 받을때 DTO로 받고, Repository에서 엔티티로 다시 변환하는 모델을 생각하는데요 엔티티로 받아서 Repository 작업 후, Controller에 값을 넘겨줄 시기에 DTO로 변환해서 사용하는것은 설계가 잘못된 것인지 궁금합니다. 일종의 꼼수의 느낌이 나는데, 이렇게 사용하면 안되는지 질문 드립니다.
-
미해결실무에서 바로 쓰는 영어 이메일
강의자료 요청드립니다
안녕하세요, 강의 잘 듣고 있습니다. 강의자료 요청드립니다(duswwns@gmail.com) 중간에 나오는 과제 첨삭의 경우 강사님께 메일을 보내서 진행하는 건가요? 게시판에 올리기에는 좀 그래서요ㅎㅎ 감사합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part2: 게임 수학과 DirectX12
Shadow RT이 SV_Target인가요?
// g_tex_2 : Shadow RT 이게 g_tex_2 텍스처 2번을 아까 우리가 셰도우 쉐이더에서 렌더 타깃으로 적어준 그 애을 사용해가지고 넘겨받아가지고 걔를 이제 사용할 것이라고 하셨는데 shadow.fx에서 target은 SV_Target 이거니까 Shadow RT이 SV_Target이고 SV_Target값을 lighting.fx에서 g_tex_2로 넘겨 받았다는 의미가 되는 건가요?
-
미해결[개정판] 딥러닝 컴퓨터 비전 완벽 가이드
clear_output() 관련
안녕하세요. 파이토치 버전과 GPU를 확인하는 셀에서 clear_output() 메서드를 실행하셨는데요, clear_output()은 셀의 출력 결과를 지우는 기능을 하는 걸로 알고 있습니다. 그런데 해당 셀에서는 clear_output()을 넣지 않아도 될 것 같은데, 넣으신 이유가 따로 있으신가요? 넣든 넣지 않든 결과는 print()로 명확히 출력한 결과만 떠서요. ㅎㅎ
-
미해결[개정판] 딥러닝 컴퓨터 비전 완벽 가이드
customdataset 구성 질문
안녕하세요!! 저는 bdd100k dataset을 이용해 mmdetection framework를 이용해 보려고 하는데요 bdd100k는 json파일로 이루어져있고 우선 강의를 통해 mmdetection의 customdataset으로 만들때 data_info와 data_anno을 만들어 dict파일을 만들어야 된다는 것은 이해했습니다. 그러면 data_info와 data_anno를 구성하기 위해 bdd100k의 json파일에서 필요한 정보를 가져와야되는데 강의의 dataset과는 많이 다른 방식이다보니 어떻게 가져와야될지에 대해 했갈리는 부분이 많아서 강사님이라면 어떻게 접근하셨을지에 대해서 여쭙고 싶습니다. 아래는 json파일의 일부이며 데이터가 이미지 갯수만큼 있는 파일입니다. { "name": "0000f77c-6257be58.jpg", "attributes": { "weather": "clear", "timeofday": "daytime", "scene": "city street" }, "timestamp": 10000, "labels": [ { "id": "0", "attributes": { "occluded": false, "truncated": false, "trafficLightColor": "G" }, "category": "traffic light", "box2d": { "x1": 1125.902264, "y1": 133.184488, "x2": 1156.978645, "y2": 210.875445 } }, { "id": "1", "attributes": { "occluded": false, "truncated": false, "trafficLightColor": "G" }, "category": "traffic light", "box2d": { "x1": 1156.978645, "y1": 136.637417, "x2": 1191.50796, "y2": 210.875443 } }, { "id": "2", "attributes": { "occluded": false, "truncated": false, "trafficLightColor": "NA" }, "category": "traffic sign", "box2d": { "x1": 1105.66915985699, "y1": 211.122087, "x2": 1170.79037, "y2": 233.566141 } }, { "id": "3", "attributes": { "occluded": false, "truncated": true, "trafficLightColor": "NA" }, "category": "traffic sign", "box2d": { "x1": 0.0, "y1": 0.246631, "x2": 100.381647, "y2": 122.825696 } }, { "id": "4", "attributes": { "occluded": false, "truncated": false, "trafficLightColor": "NA" }, "category": "car", "box2d": { "x1": 49.44476737704903, "y1": 254.530367, "x2": 357.805838, "y2": 487.906215 } }, { "id": "5", "attributes": { "occluded": false, "truncated": false, "trafficLightColor": "NA" }, "category": "car", "box2d": { "x1": 507.82755, "y1": 221.727518, "x2": 908.367588, "y2": 441.0052451528153 } }, { "id": "6", "attributes": { "occluded": false, "truncated": true, "trafficLightColor": "NA" }, "category": "traffic sign", "box2d": { "x1": 0.156955, "y1": 0.809282, "x2": 102.417429, "y2": 133.411856 } } ] }
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
/* 필터링
안녕하세요! 프론트 컨트롤러 부분에서 하나 질문드립니다! 제가 예전에 서블릿으로 했던 프로젝트를 강의를 들으면서 프론트 컨트롤러 패턴으로 바꿔보려고 합니다. 그런데 프론트 컨트롤러의 URL 패턴을 "/*"로 하니까 컨트롤러의 작업을 끝내고 포워딩할 때 주소가 "/WEB-INF/views/~~.jsp"니까 프론트 컨트롤러를 다시 한번 들어오게 되더라구요. 밑에 사진처럼요.. 혹시 이거를 서블릿만으로 필터링할 수 있는 방법이 있을까요??? 아니면 URL 패턴 설계를 다시하는 방법밖에 없을까요??
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part2: 게임 수학과 DirectX12
z를 w로 나눠서 투영좌표계를 기준으로 한 z값이 나온다고 할 때
shadoiw.fx에서 float4 PS_Main(VS_OUT input) : SV_Target { return float4(input.clipPos.z / input.clipPos.w, 0.f, 0.f, 0.f); } 클립 포지션 z랑 w를 이렇게 나눠주게 되면은 실질적으로 우리가 원했던 투영 좌표계를 기준으로 한 z 값이 튀어 나온다고 하셨는데 w라는게 xyzw의 w 좌표가 아니라 world할 때의 w 인건가요?