Heim >Backend-Entwicklung >Python-Tutorial >Verwendung des Tornado-Frameworks von Python zur Implementierung einer webseitigen Buchanzeigeseite
Erst einmal: Warum Tornado wählen:
1. Hochleistungs-Netzwerkbibliothek, die mit Gevent, Twisted, Libevent usw. gekoppelt werden kann.
Bietet asynchrone E/A-Unterstützung, Verarbeitung von Timeout-Ereignissen und stellt auf dieser Basis TCPserver, httpclient, insbesondere curlhttpclient,
bereit
Unter den bestehenden http-Clients steht es definitiv an erster Stelle. Es kann für Crawler und Gameserver verwendet werden. Soweit ich weiß, hat die Branche Tornado als Gameserver verwendet
2. Web-Framework, das mit Django und Flask verglichen werden kann.
Stellt wesentliche Komponenten von Web-Frameworks wie Routing und Vorlagen bereit. Der Unterschied zu anderen besteht darin, dass Tornado asynchron ist und sich von Natur aus für Langstreckentraining eignet,
Dies ist auch der Grund, warum Friendfeed Tornado erfunden hat. Derzeit kann es auch von Flask unterstützt werden, es muss jedoch Gevent usw. verwendet werden.
3. Ein relativ vollständiger http-Server, der mit Nginx und Apache verglichen werden kann,
Da es jedoch nur http1.0 unterstützt, dient die Verwendung von Nginx für das Frontend nicht nur der besseren Nutzung von Multi-Core, sondern auch der Unterstützung von http1.1
4. Vollständiger WSGI-Server, der mit Gunicore und Gevent WSGI-Server verglichen werden kann,
Mit anderen Worten: Sie können die Flasche über dem Tornado laufen lassen und die Flasche durch den Tornado beschleunigen lassen
5. Bietet vollständige WebSocket-Unterstützung, was HTML5-Spiele bequem macht.
Zum Beispiel verwendet Zhihu Long Rotation Training WebSocket, aber die WebSocket-Mobiltelefonunterstützung ist nicht sehr gut,
Vor einiger Zeit musste ich geplantes Ajax verwenden, um eine große Anzahl von Anfragen zu senden. Ich hoffe, dass mobile Browser bald nachholen
Verwenden Sie Tornado, um eine einfache Bucheinführungsseite zu erstellen
Okay, kommen wir zur Sache, werfen wir einen Blick auf die Code-Implementierung dieser Bucheinführungsseite:
1. Erstellen Sie eine Webdienst-Eintragsdatei blockmain.py
#coding:utf-8 import tornado.web import tornado.httpserver import tornado.ioloop import tornado.options import os.path import json import urllib2 from tornado.options import define, options define("port", default=8000, help="run on the given port", type=int) class MainHandler(tornado.web.RequestHandler): def get(self): self.render( "index.html", page_title = "Burt's Books ¦ Home", header_text = "Welcome to Burt's Books!", books = ['细说php','python','PHP','小时代'] ) class HelloModule(tornado.web.UIModule): def render(self): return'<h1>I am yyx and this is an information from module hello!</h1>' class BookModule(tornado.web.UIModule): def render(self,bookname): doubanapi = r'https://api.douban.com/v2/book/' searchapi = r'https://api.douban.com/v2/book/search?q=' searchurl = searchapi+bookname searchresult = urllib2.urlopen(searchurl).read() bookid = json.loads(searchresult)['books'][0]['id'] bookurl = doubanapi+bookid injson = urllib2.urlopen(bookurl).read() bookinfo = json.loads(injson) return self.render_string('modules/book.html',book = bookinfo) def embedded_javascript(self): return "document.write(\"hi!\")" def embedded_css(self): return '''.book {background-color:#F5F5F5} .book_body{color:red} ''' def html_body(self): return '<script>document.write("Hello!")</script>' if __name__ == "__main__": tornado.options.parse_command_line() app = tornado.web.Application( handlers = [ (r'/',MainHandler), ], template_path = os.path.join(os.path.dirname(__file__),'templates'), static_path = os.path.join(os.path.dirname(__file__),'static'), debug = True, ui_modules={'Hello':HelloModule,'Book':BookModule} ) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start()
Erklären Sie einige grundlegende MVC-Konzepte:
Tornado verwendet auch den Pathinfo-Modus, um die Eingaben des Benutzers abzugleichen, um Parameter zu erhalten, und ruft dann die entsprechende Verarbeitungsfunktion auf. Die Verarbeitung erfolgt durch Festlegen entsprechender Klassenklassen für verschiedene Übereinstimmungsmodi. Ich verwende beispielsweise die Klasse MainHandler, um die Daten von / get zu verarbeiten Anfrage
MainHandler rendert die Anfrage an index.html und die Parameter werden über {{parameters}} in index.html
2. Erstellen Sie zunächst eine grundlegende übergeordnete Klasse main.html-Vorlage, erstellen Sie das Vorlagenverzeichnis und erstellen Sie darunter main.html. Diese Vorlage definiert nur das grundlegendste Webseiten-Framework und den spezifischen Inhalt Erben Sie von seinen Unterklassen, um sie gezielt zu implementieren
<html> <head> <title>{{ page_title }}</title> <link rel="stylesheet" href="{{ static_url("css/style.css") }}" /> </head> <body> <div id="container"> <header> {% block header %}<h1>Burt's Books</h1>{% end %} </header> <div id="main"> <div id="content"> {% block body %}{% end %} </div> </div> <footer> {% set mailLink = '<a href="mailto:contact@burtsbooks.com">Contact Us</a>' %} {% set script = '<script>alert("hello")</script>' %} {% block footer %} <p> For more information about our selection, hours or events, please email us at{% raw mailLink %} <!-- {% raw script %} 这里将原样输出,也就是会弹一个框--> </p> {% end %} </footer> </div> <script src="{{ static_url("js/script.js") }}"></script> </body> </html>
Hier ist ein Hauptrahmen definiert, in dem {% Block Header %}4a249f0d628e2318394fd9b75b4636b1Burt's Books473f0a7621bec819994bb5020d29372a{% End %} ein Block für die Vererbung von Unterklassenvorlagen ist, wenn die Unterklasse dies erbt main.html. Der in diesem Block geschriebene spezifische Inhalt wird von der Unterklasse implementiert. Wenn er nicht implementiert ist, wird der Standardwert der übergeordneten Klasse verwendet Die MainHandler-Klasse wird in eine index.html gerendert und dann eine index.html geschrieben, um diese übergeordnete Klasse zu erben
{% extends "main.html" %} {% block header %} <h1>{{ header_text }}</h1> {% end %} {% block body %} <div id="hello"> <p>Welcome to Burt's Books!</p> {% module Hello() %} {% for book in books %} {% module Book(book) %} {% end %} <p>...</p> </div> {% end %}
Es ist einfach und prägnant. Dies ist auch der Vorteil der Verwendung von Vererbung. Sie müssen nicht wiederholt Dinge in die übergeordnete Klasse schreiben. Sie müssen nur den Blockinhalt der übergeordneten Klasse implementieren
Parameter in der Render-Methode in der MainHandler-Klasse
page_title = "Burt's Books | Home", header_text = "Welcome to Burt's Books!", books = ['细说php','python','PHP','小时代']Es wird über Parameter hierher gesendet
Sie können Python-Code in der Tornado-Vorlage verwenden und {% %} hinzufügen. Wenn Sie if für while usw. verwenden, verwenden Sie {% end %} am Ende
Im Code ruft {% module Book(book) %} die Definition in der Eintragsdienstdatei und das Modul auf, das „Book“ entspricht
ui_modules={'Hello':HelloModule,'Book':BookModule} ist BookModule, überprüfen Sie die BookModule-Definition oben
class BookModule(tornado.web.UIModule): def render(self,bookname): doubanapi = r'https://api.douban.com/v2/book/' searchapi = r'https://api.douban.com/v2/book/search?q=' searchurl = searchapi+bookname searchresult = urllib2.urlopen(searchurl).read() bookid = json.loads(searchresult)['books'][0]['id'] bookurl = doubanapi+bookid injson = urllib2.urlopen(bookurl).read() bookinfo = json.loads(injson) return self.render_string('modules/book.html',book = bookinfo)BookModule erbt von tornado.web.UIModule. Die Verwendung des UI-Moduls ist die render_string()-Methode, um ein Objekt hier in eine Vorlage umzuwandeln und es zunächst über die Suche nach Buchinformationen abzufragen , geben Sie die ID des ersten Buches zurück, fragen Sie dann mit der Buch-API die spezifischen Informationen des Buches ab und rendern Sie die Informationen dieses spezifischen Buchs in die entsprechende Vorlage
Erstellen Sie das Modulverzeichnis unter dem Vorlagenverzeichnis und erstellen Sie dann eine book.html. Hier ist der spezifische Inhaltsrahmen, der im Buch angezeigt werden soll
<div class="book"> <h3 class="book_title">{{ book["title"] }}</h3> <a href="{{book['alt']}}" target="_blank"><p>点击查看详情</p></a> {% if book["subtitle"] != "" %} <h4 class="book_subtitle">{{ book["subtitle"] }}</h4> {% end %} <img src="{{ book["images"]["large"] }}" class="book_image"/> <div class="book_details"> <div class="book_date_released">Released: {{ book["pubdate"]}}</div> <h5>Description:</h5> <div class="book_body">{% raw book["summary"] %}</div> </div> </div>Die endgültige Dateiverzeichnisstruktur sollte so aussehen
├── blockmain.py └── templates ├── index.html ├── main.html └── modules └── book.htmlDie Ausführung des Programms ist wie folgt:
Verwenden Sie zunächst die MainHandler-Klasse, um über den Pfad '/'---->index.html erbt von main.html---->{% module Book(book) %} in index.html auf index.html zuzugreifen Umgekehrt. Suchen Sie die ui_modules, die Book in blockmain.py---->ui_modules entsprechen, und rendern Sie den Inhalt des abgefragten Buchobjekts in book.html unter „modules“, sodass der vollständige Inhalt angezeigt wird, ohne dass das Frontend ausgeführt werden muss Dienst über Python blockmain.py und greifen Sie über http://localhost:8000
auf die folgende Webseite zu