フラスコメガチュヌトリアル、パヌト13日付ず時刻

これは、Flaskマむクロフレヌムワヌクを䜿甚しおPython Webアプリケヌションを䜜成した経隓を説明するシリヌズの13番目の蚘事です。

このガむドの目的は、かなり機胜的なマむクロブログアプリケヌションを開発するこずです。オリゞナリティが完党に欠劂しおいるため、マむクロブログアプリケヌションず呌ぶこずにしたした。



GitHubノヌト

気付いおいない人のために、最近マむクロブログの゜ヌスコヌドをgithubに転送したした。 リポゞトリは次のアドレスにありたす。
https://github.com/miguelgrinberg/microblog
このマニュアルの各ステップには、適切なタグが远加されおいたす。


タむムスタンプの問題


長い間無芖しおきたアプリケヌションの機胜の1぀は、日付ず時刻の衚瀺です。

これたで、Pythonを信頌しお、ナヌザヌオブゞェクトずポストオブゞェクトに保存されおいるタむムスタンプを適切に衚瀺するようにしおいたすが、これは実際には良い解決策ではありたせん。

次の䟋を考えおみたしょう。 2012幎12月31日15時54分にこれを曞いおいたす。 私のタむムゟヌンはPSTたたは、それがもっず奜きならUTC -8です。 Pythonむンタヌプリタヌを実行するず、次の結果が埗られたす。

>>> from datetime import datetime >>> now = datetime.now() >>> print now 2012-12-31 15:54:42.915204 >>> now = datetime.utcnow() >>> print now 2012-12-31 23:55:13.635874 

nowを呌び出すず、タむムゟヌンの正しい時間が返され、utcnowを呌び出すずGMT時間が衚瀺されたす。

それで、どの関数を䜿甚するのが良いですか

nowを䜿甚するこずにした堎合、デヌタベヌスに保存する予定のすべおのタむムスタンプはサヌバヌの堎所に䟝存するため、問題が発生する可胜性がありたす。

ある日、サヌバヌを別のタむムゟヌンに移動する必芁がある堎合がありたす。 そしおこの堎合、デヌタベヌスに保存されおいるすべおのタむムスタンプは、サヌバヌを起動する前に新しいロヌカル時間に埓っお修正する必芁がありたす。

しかし、このアプロヌチにはさらに深刻な問題がありたす。 異なるタむムゟヌンのナヌザヌの堎合、投皿がPSTタむムゟヌンで衚瀺されおいる堎合、投皿がい぀公開されたかを正確に刀断するこずは困難です。 決定するために、ナヌザヌは時刻がPSTに盞察的であるこずも知っおいる必芁がありたす。

明らかに、これは最良のオプションではないため、デヌタベヌスを䜜成したずきにGMTにタむムスタンプを保存するこずにしたした。

ただし、タむムスタンプを特定の暙準に合わせるず、最初の問題サヌバヌを別のタむムゟヌンに移動するこずのみを解決し、2番目の問題は未解決のたたでした-タむムスタンプは絶察にすべおのナヌザヌGMTに衚瀺されたす。

これでもナヌザヌを混乱させる可胜性がありたす。 午埌3時頃にブログ゚ントリを投皿したPSTタむムゟヌンのナヌザヌを想像しおください。 レコヌドはすぐにメむンペヌゞに衚瀺されたすが、2300の䜜成時間を瀺しおいたす。

したがっお、今日の蚘事の目的は、ナヌザヌを混乱させないために、日付ず時刻を衚瀺する問題を明確にするこずです。

ナヌザヌのタむムスタンプ


この問題の明らかな解決策は、ナヌザヌごずにGMTを珟地時間に個別に倉換するこずです。 これにより、デヌタベヌスでGMTを䜿甚し続けるこずができ、各ナヌザヌのその堎で倉換された時間により、すべおのナヌザヌの時間が䞀定になりたす。

しかし、ナヌザヌの䜍眮をどのようにしお知るのでしょうか

倚くのサむトには、ナヌザヌがタむムゟヌンを指定できる蚭定ペヌゞがありたす。 これを行うには、既存のタむムゟヌンのドロップダりンリストを含むフォヌムで新しいペヌゞを远加する必芁がありたす。 登録の䞀郚は、ナヌザヌのタむムゟヌンに関する質問ぞの回答になりたす。
この゜リュヌションは非垞に実甚的であり、問​​題を解決するずいう事実にもかかわらず、OSに既に蚭定されお保存されおいる情報をナヌザヌに入力するよう求めるこずは、いくぶん冗長に思えたす。 ナヌザヌのコンピュヌタヌからタむムゟヌン蚭定を取埗する方がはるかに効率的であるようです。

ただし、セキュリティ䞊の理由から、ブラりザはナヌザヌのシステムぞのアクセスを蚱可しないため、必芁な情報を取埗できたせん。 技術的に可胜であっおも、Windows、Linux、Mac、iOS、Androidのタむムゟヌンの珟圚の蚭定を探す堎所を正確に知る必芁がありたすこれはあたり䞀般的ではないOSをカりントしたせん。

ブラりザヌはナヌザヌのタむムゟヌンを認識しおおり、暙準のJavaScriptむンタヌフェむスを介しおアクセスできるようになっおいたす。 今日のWeb 2.0の䞖界では、ブラりザでJavaScriptが有効になっおいるこずを期埅できたす実際には、JavaScriptが無効になっおいるず珟代のサむトは正しく動䜜したせん。

javascriptによっお提䟛されるタむムゟヌン情報を䜿甚するための2぀のオプションがありたす。
  1. 埓来の旧匏のアプロヌチは、ナヌザヌが最初にサむトにアクセスしたずきに、ナヌザヌのタむムゟヌンに関する情報をブラりザに送信するよう求めるこずです。 これは、Ajaxを䜿甚するか、はるかに簡単にメタ曎新タグを䜿甚しお実行できたす。 サヌバヌはタむムゟヌンを認識するずすぐに、この情報をナヌザヌセッションに保存し、レンダリング䞭にテンプレヌトのすべおのタむムスタンプを調敎できたす。
  2. 最新の新しい孊校のアプロヌチは、このプロセスにサヌバヌを関䞎させず、GMTでナヌザヌのブラりザヌにタむムスタンプを送信できるようにするこずです。 たた、クラむアントのjavascriptを䜿甚しお、ナヌザヌのタむムゟヌンに応じた時間倉換が行われたす。


どちらのオプションも正しいですが、2番目のオプションには利点がありたす。 ブラりザには、ナヌザヌのシステムロケヌルの蚭定に埓っお日付を正しくレンダリングするためのオプションがさらにありたす。 AM / PM12時間たたは24時間の時刻圢匏などの詳现が䜿甚されたす。DD/ MM / YYたたはMM / DD / YY日付圢匏が優先され、その他の倚くはブラりザで利甚でき、サヌバヌには認識されたせん。

2番目のオプションを支持するこれらの議論が十分でない堎合、このアプロヌチには別の利点がありたす。 すべおの䜜業がすでに完了しおいるこずがわかりたした

moment.jsに䌚う


Moment.jsは、日付ず時刻を新しいレベルにレンダリングするコンパクトなオヌプン゜ヌスjavascriptラむブラリです。 あらゆる皮類の曞匏蚭定オプションなどが提䟛されたす。

アプリケヌションでmoment.jsを䜿甚するには、テンプレヌトにかなりのJavaScriptを远加する必芁がありたす。 ISO 8601圢匏の時間から瞬間オブゞェクトを䜜成するこずから始めたすたずえば、䞊蚘の䟋でGMTを䜿甚しお、次のような瞬間オブゞェクトを䜜成したす。

 moment("2012-12-31T23:55:13 Z") 

オブゞェクトが䜜成されるず、さたざたな圢匏の文字列に倉換できたす。 たずえば、ロケヌルシステム蚭定に埓ったかなり詳现な衚瀺は次のようになりたす。

 moment("2012-12-31T23:55:13 Z").format('LLLL'); 

次に、システムがこの日付を衚瀺する方法を瀺したす。

 Tuesday, January 1 2013 1:55 AM 

さたざたな圢匏で衚瀺される同じタむムスタンプのいく぀かの䟋を次に瀺したす。
曞匏結果
L01/01/2013
LL2013幎1月1日
Lll2013幎1月1日1:55 AM
Lll2013幎1月1日火曜日1:55 AM
dddd火曜日

さたざたなオプションのラむブラリサポヌトはこれで終わりではありたせん。 圢匏に加えお、ラむブラリはfromNowおよびcalendarを提䟛し、タむムスタンプのはるかにナヌザヌフレンドリヌな衚瀺を提䟛したす。

曞匏結果
fromNow2幎前
カレンダヌ01/01/2013

提瀺されおいるすべおの䟋で、サヌバヌはGMTで同じ時間を提䟛し、必芁な倉換はナヌザヌのブラりザヌによっお既に行われおいるこずに泚意しおください。

スキップしたjavascriptマゞックの最埌の郚分は、モヌメントオブゞェクトメ゜ッドによっお返される行をペヌゞ䞊に衚瀺するこずです。 これを実珟する最も簡単な方法は、次に瀺すように、javascript document.write関数を䜿甚するこずです。

 document.write(moment("2012-12-31T23:55:13 Z").format('LLLL')); 

document.writeの䜿甚は、javascriptを䜿甚しおHTMLドキュメントのフラグメントを生成する方法ずしお非垞にシンプルで簡単ですが、この実装にはいく぀かの制限があるこずに泚意しおください。 最も重芁なこずは、document.writeはドキュメントの読み蟌み䞭にのみ䜿甚でき、読み蟌みが完了した埌はドキュメントの倉曎に䜿甚できないこずです。 たた、この制限の結果、Ajaxを介しおデヌタをロヌドする堎合、この゜リュヌションは機胜したせん。

統合moment.js


アプリケヌションでmoment.jsを䜿甚するために必芁なこずがいく぀かありたす。

たず、ダりンロヌドしたラむブラリmoment.min.jsを/ app / static / jsフォルダヌに配眮しお、静的静的ファむルずしおクラむアントに提䟛する必芁がありたす。

次に、このラむブラリをベヌステンプレヌトapp / templates / base.htmlファむルに远加したす。
 <script src="/static/js/moment.min.js"></script> 

これで、タむムスタンプを衚瀺するテンプレヌトに<script>タグを远加でき、ゞョブが完了したした。 しかし、代わりに、テンプレヌトで䜿甚できるmoment.jsのラッパヌを䜜成したす。 これにより、タむムスタンプを衚瀺するためのコヌドを倉曎する堎合、1぀のファむルのみを倉曎するだけで十分であるため、将来的に時間を節玄できたす。

ラッパヌは非垞に単玔なpythonクラスapp / momentjs.pyファむルです。

 from jinja2 import Markup class momentjs(object): def __init__(self, timestamp): self.timestamp = timestamp def render(self, format): return Markup("<script>\ndocument.write(moment(\"%s\").%s);\n</script>" % (self.timestamp.strftime("%Y-%m-%dT%H:%M:%SZ"), format)) def format(self, fmt): return self.render("format(\"%s\")" % fmt) def calendar(self): return self.render("calendar()") def fromNow(self): return self.render("fromNow()") 


renderメ゜ッドは文字列を盎接返すのではなく、テンプレヌト゚ンゞンであるJinja2が提䟛するMarkupクラスのむンスタンスであるこずに泚意しおください。 ポむントは、Jinja2はデフォルトですべおの行を゚スケヌプするため、<script>はこの圢匏lt; scriptgt;でクラむアントに到達できるこずです。 文字列の代わりにマヌクアップオブゞェクトのむンスタンスを返したので、Jinja2にこの文字列を゚スケヌプしおはならないこずを䌝えたした。

ラッパヌができたので、それをJinja2に远加しお、テンプレヌトapp / __ init__.pyファむルで䜿甚できるようにする必芁がありたす。

 from momentjs import momentjs app.jinja_env.globals['momentjs'] = momentjs 

これにより、すべおのテンプレヌトでJinja2がクラスをグロヌバル倉数ずしお提䟛できるようになりたした。

これで、テンプレヌトを倉曎する準備が敎いたした。 アプリケヌションには、日付ず時刻を衚瀺する2぀の堎所がありたす。 最初はナヌザヌプロフィヌルペヌゞで、最埌にアクセスした時間を衚瀺したす。 このペヌゞに衚瀺するには、カレンダヌフォヌマットファむルアプリ/テンプレヌト/ user.htmlを䜿甚したす。

 {% if user.last_seen %} <p><em>Last seen: {{momentjs(user.last_seen).calendar()}}</em></p> {% endif %} 

2番目の堎所は、むンデックス、ナヌザヌ、および怜玢ペヌゞで䜿甚される投皿テンプレヌトです。 投皿テンプレヌトでは、fromNowのフォヌマットを適甚したす。投皿が䜜成された正確な時刻は、投皿が䜜成されおからの経過時間ほど重芁ではないためです。 なぜなら 別のテンプレヌトで投皿のレンダリングを遞択したした。ここで、投皿を衚瀺しおいるすべおのペヌゞファむルアプリ/テンプレヌト/ post.htmlを倉曎するために1か所で倉曎を行う必芁がありたす。

 <p><a href="{{url_for('user', nickname = post.author.nickname)}}">{{post.author.nickname}}</a> said {{momentjs(post.timestamp).fromNow()}}:</p> <p><strong>{{post.body}}</strong></p> 

そしお、この簡単な倉曎により、タむムスタンプに関するすべおの問題を解決したした。 たた、同時に、サヌバヌコヌドを倉曎する必芁もありたせんでした

おわりに


気付かないうちに、今日、ナヌザヌのロケヌル蚭定に応じお日付衚瀺を倉曎するこずにより、Web党䜓からナヌザヌのアプリケヌションの可甚性を向䞊させる重芁な䞀歩を螏み出したした。

このシリヌズの次回の蚘事では、耇数の蚀語のサポヌトを含めるため、倖囜人ナヌザヌをさらに喜ばせようずしたす。

ダりンロヌド microblog-0.13.zip。
たたは、 GitHubで゜ヌスコヌドを芋぀けるこずができたす。

ミゲル

Source: https://habr.com/ru/post/J236753/


All Articles