Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A Scenic Drive through the Django Request-Response Cycle

A Scenic Drive through the Django Request-Response Cycle

Ever wonder how a request gets from your computer, out to the internet, and then back as a response? I did, so I decided to talk about it.

This is the story of how pressing "Enter" on a curl command gets you something back.

Dan Langer

April 12, 2014
Tweet

More Decks by Dan Langer

Other Decks in Programming

Transcript

  1. WEB SERVER GATEWAY INTERFACE def simple_app(environ, start_response): response_headers = [('Content-type',

    'text/plain')] start_response(‘200 OK’, response_headers) return ['Hello world!\n']
  2. DJANGO SPEAKS WSGI class WSGIHandler(base.BaseHandler): def __call__(self, environ, start_response): [...]

    response = self.get_response(request) [...] start_response(status, response_headers) return response
  3. MIDDLEWARE A small digression “[A] light, low-level ‘plugin’ system for

    globally altering Django’s input or output.” - https://docs.djangoproject.com/en/dev/topics/http/middleware/
  4. DJANGO.CORE.URLRESOLVERS urlpatterns = patterns('' url(r'^hello/(?P<city>\w+)/$', HiCityView, name=‘hi_city’), ) {% url

    ‘hi_city’ city=ottawa %} reverse(‘hi_city’, kwargs={‘city’: ‘ottawa’}) # Both return http://www.daniellanger.com/hello/ottawa/
  5. DJANGO.CORE.URLRESOLVERS urlpatterns = patterns('' url(r'^cdn_hi/(?P<city>\w+)/$', HiCityView, name=‘hi_city’), ) {% url

    ‘hi_city’ city=ottawa %} reverse(‘hi_city’, kwargs={‘city’: ‘ottawa’}) # Both return http://www.daniellanger.com/cdn_hi/ottawa/
  6. CLASS-BASED VIEWS from django.views.generic import View class HiMtlView(View): def get(self,

    request): html = “Bonjour <b>Mtl</b>!” return HttpResponse(html)
  7. TEMPLATES IN VIEWS from django.shortcuts import render def HiMtlView(request): context

    = {‘city’: ‘Montreal’} return render(request, ‘hello.html’, context) # hello.html Bonjour <b>{{ city }}</b>!
  8. TEMPLATES IN VIEWS def HiMtlView(request): context = {‘city’: ‘Montreal’} return

    render(request, ‘hello.html’, context) # hello.html Bonjour <b>{{ city }}</b> (from {{ request_city }}!)
  9. TEMPLATES IN VIEWS def HiMtlView(request): context = { ‘city’: ‘Montreal’,

    ‘request_city’: GeoIP.get_city(request)} return render(request, ‘hello.html’, context) # hello.html Bonjour <b>{{ city }}</b> (from {{ request_city }}!)
  10. CONTEXT PROCESSORS def HiMtlView(request): context = { ‘city’: ‘Montreal’, ‘request_city’:

    GeoIP.get_city(request)} return render(request, ‘hello.html’, context) # hello.html Bonjour <b>{{ city }}</b> (from {{ request_city }}!)
  11. CONTEXT PROCESSORS def HiMtlView(request): context = {‘city’: ‘Montreal’} return render(request,

    ‘hello.html’, context) # hello.html Bonjour <b>{{ city }}</b> (from {{ request_city }}!)
  12. MIDDLEWARE class PyConMiddleware(object): def process_request(self, request): return None # or

    HttpResponse def process_response(self, request, response): return response # or new HttpResponse
  13. WEB SERVER GATEWAY INTERFACE class WSGIHandler(base.BaseHandler): def __call__(self, environ, start_response):

    [...] response = self.get_response(request) [...] start_response(status, response_headers) return response
  14. THE RESPONSE $ curl -v http://www.daniellanger.com/hello/mtl/ > GET /hello/mtl/ HTTP/1.1

    > Host: www.daniellanger.com > Accept: */* < HTTP/1.1 200 OK < Server: nginx < Content-Type: text/html;charset=UTF-8 < Content-Length: 33 Bonjour Montreal! (from Toronto)
  15. CLIENT WEB SERVER WSGI URL RESOLUTION VIEW WSGI WEB SERVER

    CLIENT REQUEST Middleware RESPONSE Middleware VIEW Middleware EXCEPTION Middleware