Übermäßig vereinfacht: Sie benötigen etwas, das Python ausführt, aber Python kann nicht alle Arten von Anforderungen am besten verarbeiten.
[Haftungsausschluss: Ich bin ein Gunicorn-Entwickler]
Weniger vereinfacht: Unabhängig davon, welchen App-Server Sie verwenden (Gunicorn, mod_wsgi, mod_uwsgi, cherrypy), hat jede Art von nicht-trivialer Bereitstellung einen Upstream, der die Anforderungen verarbeitet, die Ihre Django-App nicht verarbeiten sollte. Triviale Beispiele für solche Anforderungen sind die Bereitstellung statischer Elemente (images / css / js).
Dies führt zu zwei ersten Ebenen der klassischen "dreistufigen Architektur". Das heißt, der Webserver (in Ihrem Fall Nginx) verarbeitet viele Anfragen nach Bildern und statischen Ressourcen. Anforderungen, die dynamisch generiert werden müssen, werden dann an den Anwendungsserver (in Ihrem Beispiel Gunicorn) weitergeleitet. (Abgesehen davon ist die dritte der drei Ebenen die Datenbank)
Historisch gesehen würde jede dieser Ebenen auf separaten Maschinen gehostet (und es würde höchstwahrscheinlich mehrere Maschinen in den ersten beiden Ebenen geben, dh: 5 Webserver senden Anforderungen an zwei App-Server, die wiederum eine einzelne Datenbank abfragen).
In der Neuzeit haben wir jetzt Anwendungen in allen Formen und Größen. Nicht jedes Wochenendprojekt oder jede Website für kleine Unternehmen benötigt die Leistung mehrerer Maschinen und kann problemlos auf einer einzigen Box ausgeführt werden. Dies hat zu neuen Einträgen in die Reihe der Hosting-Lösungen geführt. Einige Lösungen verbinden den App-Server mit dem Webserver (Apache httpd + mod_wsgi, Nginx + mod_uwsgi usw.). Und es ist keineswegs ungewöhnlich, die Datenbank auf demselben Computer wie eine dieser Web- / App-Server-Kombinationen zu hosten.
Im Fall von Gunicorn haben wir eine spezielle Entscheidung getroffen (Kopieren von Ruby's Unicorn), um die Dinge von Nginx zu trennen, während wir uns auf das Proxy-Verhalten von Nginx verlassen. Insbesondere wenn wir davon ausgehen können, dass Gunicorn niemals Verbindungen direkt aus dem Internet liest, müssen wir uns keine Sorgen um langsame Clients machen. Dies bedeutet, dass das Verarbeitungsmodell für Gunicorn peinlich einfach ist.
Durch die Trennung kann Gunicorn auch in reinem Python geschrieben werden, wodurch die Entwicklungskosten minimiert und die Leistung nicht wesentlich beeinträchtigt werden. Außerdem können Benutzer andere Proxys verwenden (vorausgesetzt, sie puffern ordnungsgemäß).
Was Ihre zweite Frage anbelangt, was die HTTP-Anfrage tatsächlich behandelt, lautet die einfache Antwort Gunicorn. Die vollständige Antwort ist, dass sowohl Nginx als auch Gunicorn die Anfrage bearbeiten. Grundsätzlich erhält Nginx die Anfrage, und wenn es sich um eine dynamische Anfrage handelt (im Allgemeinen basierend auf URL-Mustern), gibt es diese Anfrage an Gunicorn weiter, der sie verarbeitet, und sendet dann eine Antwort an Nginx zurück, die die Antwort dann an das Original weiterleitet Klient.
Also zum Schluss ja. Sie benötigen sowohl Nginx als auch Gunicorn (oder etwas Ähnliches) für eine ordnungsgemäße Django-Bereitstellung. Wenn Sie speziell Django mit Nginx hosten möchten, würde ich Gunicorn, mod_uwsgi und vielleicht CherryPy als Kandidaten für die Django-Seite der Dinge untersuchen.