• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

jinja2.exceptions.UndefinedError

20.04.18 23:56 작성 조회수 1.88k

1

list.html 상에 시간을 표시하는 부분에서

<td>{{data.pubdate|formatdatetime}}</td>

위와 같이 formatdatetime 를 넣으면 

jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'pubdate'

위와 같이 에러가 발생하고, 아래와 같이 해당 부분을 삭제하면

<td>{{data.pubdate}}</td>

시간이 원하는 형태로 출력이 되지는 않지만, 에러없이 리스트가 나옵니다.

원인이 뭘까요?

상세보기 실습인 view.html 에서는 이상없이 출력이 됐었는데요.

오타가 있는지도 계속 살펴보는데 이유를 모르겠습니다.

답변 5

·

답변을 작성해보세요.

0

몽고DB는 비정규화된 데이터를 저장하는데 특징이 있습니다. 또한 대용량 빅데이터를 순간적으로 저장하는데 강점이 있습니다. 많은 업체들이 몽고DB로 전환하는곳이 많습니다만 서비스의 목적성에 부합하는지를 생각해보는것도 나쁘지 않습니다. 물론 어떤 결론을 내리기전 내가 충분히 테스트를 하였느냐도 중요한 부분입니다.

0

accto님의 프로필

accto

질문자

2020.04.20

답변감사드립니다. 몽고DB는 처음 접해보는데, 낯설어서 그런지 아직은 마냥 어렵다는 생각밖에 안드네요. ㅋ

제가 구현하려고 생각하는게 있는데, 몽고 DB로 가능할지 심사숙고 해봐야 할거 같습니다.

수고하세요.

0

몽고DB는 말씀하신대로 데이터마다의 필드를 가질 수 있습니다. 그런데 이게 장점이기도 하지만 단점이 될 수 있는 상황이 위와 같은 상황이 발생할 수 있다는 점입니다만 그래서 몽고DB의 각 필드를 모델링하여 객체처럼 사용하는 방식도 있습니다만 저는 개인적으로 추천하지는 않습니다. 그렇게 사용할꺼면 그냥 SQL 을 사용하는게 더 낫다고 생각합니다.

위와 같은 상황을 방어하려면 HTML로 몽고DB의 커서를 넘기지 않고 data 를 하나의 dict 형태로 따로 처리해서 파이썬 코드에서 선처리 후 해당 dict 를 html 로 넘길 수 있습니다.

datas = db.find({})

result_data = []
for data in datas:
	result_data.append({
		"idx": data.get("idx"),
		"pubdate": data.get("pubdate")
	})

return render_template("list.html", data=result_data)

위와 비슷한 행태로 미리 처리해서 확인 할 수도 있으니 참고 하시기 바랍니다.

프로젝트에서 데이터베이스는 사실 명확한 필드를 갖고 기획을 해야합니다. 기획단계에서 이미 정해지는 부분이 있기 때문에 사실 위와 같은 상황이 자주 발생한다는것은 기획 단계에서 수정해야할 사항이라고 생각됩니다. 

0

accto님의 프로필

accto

질문자

2020.04.19

늦은 시간에 빠른 답변 감사드립니다. 원인을 찾았습니다.

혹시 몰라서 몽고DB를 robo3T로 열어서 데이터 상태를 봤더니

목록 중에서 첫번째 document에 pubdate 필드가 없고, 나머지 google.py 를 통해 자동 입력한 데이터들에는 pubdate 필드가 있네요.

pubdate 필드가 없는 document 를 삭제하고 조회하니 정상 작동 됩니다.

여기서 추가로 질문이 생기는데요.

몽고DB 에 대해서 처음 설명해주실 때, 기존 SQL 과는 달리 동일한 테이블(collection)에서도 필드를 달리 가질 수 있다고 하셨고, 제가 경험한 문제가 발생할 일이 많을거 같은데, 이런 경우는 어떻게 예외처리를 해야 할까요

0

오류가 조금 이해가 가지 않습니다.

jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'pubdate'

이 오류 내용은 dict 객체에 pubdate가 없다는 이야기 인데 formatdatetime을 제거하면 문제 없이 출력된다는게..

전체적인 코드를 보지 않아서 정확히 답변을 드릴수 없지만 data 객체에 있는 값이 문제인지 formatdatetime 함수에 문제인지 어떤게 문제인지부터 확인해보시는게 좋을듯 합니다. 

from flask import Flask
from flask import render_template_string

import time
from datetime import datetime

app = Flask(__name__)

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

    # 현재 시간 타임스탬프를 구합니다.
    now_timestamp = time.time()
    
    # 현재 시간 타임스탬프를 현재 시간객체, UTC 시간 기준 시간객체로 변환하여
    # 현재 시간에서 UTC 시간을 빼 시간차를 구합니다.
    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("/")
def index():
    html = """
    <html>
    <body>
    {{time|formatdatetime}}
    </body>
    </html>
    """

    return render_template_string(html, time=datetime.utcnow().timestamp())


if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True, port=8000)

제가 임시로 간단한 샘플 코드를 만들어봤으니 참고하시기 바랍니다.