SlideShare a Scribd company logo
1 of 36
Download to read offline
The Three line MVC
    application
  and introducing Giotto
Table on contents

First part: Why high level code organization schemes are
important

Second part: All about MVC

Third Part: Giotto!
My experiences

1. Started web development in 2007
2. Wrote code without any kind of architectural pattern at all
3. This was very frustrating, but I didn't know any better
4. Realized it's taking too long to get stuff fixed and its not fun
5. Learned first hand that not using MVC is a pain
Non-MVC code
Flightlogg.in'
            Was originally PHP (non-MVC)
            Now is django (mostly MVC)




 View: HTML/Javascript
 Controller: Standard HTTP GET/POST
 Model: Flight Storage and flight data analysis.
Why?

1. Flexibility
2. Organization
Imagine...

1 app
1 django view, 9000 lines of code
Imagine...

We want to fix this. Refactor!!

step 1:
   1000 functions, 9 lines each
Imagine...

step 2:
   100 classes, 10 functions each
And then...

App
 Models
  class
  class
 Views
  class
  class
 Controllers
  class
  class
Overview

1. Models - The application
2. Controllers - The interface
   a. ties your application (model) to the outside world
3. Views - The presentation of the output to the user
Models

1. Usually the biggest part of your application
2. Business Logic
3. Not just database tables
4. Should be completely controller independent
Views

1. All about formatting output from model.
2. Templates/HTML
3. Serializers
4. Should be independent of any controllers (templates are
portable)
Controllers

1. How the data gets to and from the user
2. Apache, nginx, varnish, django middleware, mod_wsgi are
all technically part of the controller.
3. What goes into my controller?
   a. High level Model code
   b. High level View code
   c. final interface level operations
An example controller

def new_flight_controller(request):
  total_time = request.POST['total_time']
  landings = request.POST['landings']
  user = request.user
  flight = Flight.new_flight(user, total_time, landings)
  try:
      flight.save()
  except:
      raise HttpResponseError("invalid flight data")
  return render_to_response(
            context={'flights': Flight.objects.filter(request.user)}
            template='flights.html')
An example controller

def new_flight_controller(request):
  total_time = request.POST['total_time']
  landings = request.POST['landings'] Interface operations
  user = request.user
  flight = Flight.new_flight(user, total_time, landings)
  try:
                                    High level model code
      flight.save()
  except:
      raise HttpResponseError("invalid flight data")
  return render_to_response(
            context={'flights': Flight.objects.filter(request.user)}
            template='flights.html')
                                      High level view code
Another example controller
class NewFlightCommand(BaseCommand):
   option_list = BaseCommand.option_list + (
        make_option('--total_time', '-t', dest='total_time'),
        make_option('--landings', '-l', dest='landings'),
        make_option('--user', '-u', dest='user')
   )

  def handle(self, *args, **options):
    flight = Flight.new_flight(**options)
    try:
        flight.save()
    except:
        print "Invalid flight data"
    print "Flight saved!"
Don't put non-controller code inside a
controller!
def to_decimal(input):
  """
  >>> to_decimal('3:30')
  3.5
  >>> to_decimal('3.5')
  3.5
  >>> to_decimal('3:12')
  3.2
  """

This is not a controller function! Not high level model code, not
high level view code, and not interface specific!!!
This code is not controller code!

def controller(request):
  total_time = to_decimal(request.GET['total_time']) # bad!
  landings = request.GET['landings']
  user = request.user
  flight = Flight.new_flight(user, total_time, landings)
  try:
      flight.save()
  except:
      raise HttpResponseError("invalid flight data")
  return render_to_response(
            context={'flights': Flight.objects.filter(request.user)}
            template='flights.html')
The three line MVC application!

def mini_controller(request):
  return {total_time: request.GET['total_time'],
         landings: request.GET['landings'],
         user: request.user}

def new_flight(request):
  args = mini_controller(request)
  flight = Flight.new_flight(*args).save()
  return render_to_response('view_flight.html', {'flight': flight})
The MVC color-wheel
                   Model

  Middleware
                                    ModelViews /
                                    Forms




 Controller                         View


               Context processors
ModelViews

1. Projection of a Model (subclass) intended for use in a set of
views
2. Atomic elements that should not hinder the 'real' view's ability
to do its job.
ModelViews

class HTMLFlight(Flight):
   def as_tr(self):
     """
     >>> HTMLFlight.objects.get(pk=234321).as_tr()
     '<tr id="flight_234321"><td class="total_time">3.5</td>...
     """

class JSONFlight(Flight):
   def as_json(self):
     """
     >>> JSONFlight.objects.get(pk=56216).as_json()
     '{id: 56216, plane: {tailnumber: "N63NE", type: "SA-227"...
     """
ModelView

def list_flights_controller(request, format):
  if format == 'json':
      return JSONFlight, 'flights.json'
  elif format == 'html':
      return HTMLFlight, 'flights.html'

def list_flights(request, format):
  Flight, view = list_flights_controller(request, format)
  flights = Flight.objects.filter(user=request.user)
  return render_to_response({'flights': flights}, view)
ModelView

flights.html:
    <table class="whatever">
        {{ Flight.header }}
        {% for flight in flights %}
        {{ flight.as_tr }}
        {% endfor %}
    </table>
flights.json:
{user: {{ request.user }},
 flights:
    {% for flight in flights %}
    {{ flight.as_json }},
    {% endfor %}
}
Good models are easy to test

class BaseFlightFailedTest(object):
   exc = Flight.InvalidFlightData
   def test(self):
     for kwargs in self.kwarg_set:
        self.assertRaises(Flight.new_flight(**kwargs), self.exc)

class TotalGreatestTest(TestCase, BaseFlightFailedTest):
   exc = Flight.TotalMustBeGreatest
   kwarg_set = [{'total_time': '3:50', 'pic': 9.6},
                 {'total_time': 1.0, 'night': 2.3}]

class NoNightTime(TestCase, BaseFlightFailedTest)
   kwarg_set = [{'total_time': 1, 'night': 0, 'night_landings': 5}]
Tips:

1. Don't pass request objects into the model
   a. It couples your model to HTTP requests
   b. Models should only work with raw data

2. Try to avoid putting business logic into a controller
   a. It makes it hard to reuse models

3. Pass in only one model object to a view.
   a. if you have trouble doing this, your models may be wrong
   b. helps keep the templates reusable.

4. Make an attempt to re-write all your controllers to be
exactly 3 lines.
Giotto!

- New python web development framework!!
- Absolutely nothing has been started yet.
- Doesn't let you violate MVC.
- There should be one-- and preferably only one --obvious way
to do it.
- "MV" framework. (micro controllers)
- Completely automatic urls
- plugins for features
- plugins for controller backends. (commandline, http-get, etc)
Giotto Feature

@interfaces('http-get', 'commandline')
class ShowFlightsForUser(Feature):
   """
   Show flights for a given user
   """
   controller = {'user': Input.data.user}
   model = Flight.objects.show_for_user
   view = ShowFlights

url for feature:
{% http-get ShowFlightsForUser.html 59 %} ->

Logbook.com/flights/ShowFlightsForUser.html?user=59
Giotto Interfaces

@interfaces('http-put', 'commandline')
class NewFlight(Feature):
   """
   Create a new flight
   """
   controller = {'user': Input.data.user, 'total_time': Input.data...
   model = Logbook.Flight.create
   view = SingleFlight

Using the feature:
   $ ./giotto.py logbook NewFlight --user=chris --total_time=3 ...
or
   PUT /new_flight.json HTTP/1.1
   user=chris&total_time=3 ...
Giotto Models

class Manager(models.Manager)
   def show_for_user(self, user):
     return self.filter(user=user)

  def create(self, *args, **kwargs):
    # logic goes here
    return Flight(**kwargs)

class Flight(models.Model):
   attribute = models.Field()
   objects = Manager()
Accessing features

command line:
  $ ./giotto.py app feature format [args]

http-get
   POST app.com/feature.format HTTP/1.1
   [args]

sms
  text "feature format [args]" to 3558526


The controller backend handles transporting data to/from the
user
Controllers handle everything for you

@interfaces('http-get', 'commandline')
class ShowRouteForFlight(Feature):
   """
   Get the route for a single flight
   """
   controller = Flight.id
   model = Flight.route
   view = SingleRouteView
Giotto Views

Take only a single model instance as the only context (obj)

Views can return anything, as long as the controller backend
knows how to handle it.

templates make links to application features:

<a href="{% url_get ShowFlightsForUser obj.user %}">
  see {{ obj.user }}'s flights!
</a>
Giotto Views

class SingleRouteView(View):
   def png(self, route):
     "Given a route, return as a png image"
     return image_file

  def kml(self, route):
    return kml_string

  def html(self, route):
    return jinja2.render({'obj': route}, 'route.html')

{% http-get RouteForFlight.kml 36426 %}
{% http-get RouteForFlight.html 36426 %}
giotto logbook RouteForFlight png 36426 | file.png

More Related Content

What's hot

SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterHaehnchen
 
Workshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIWorkshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIVisual Engineering
 
Compatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensionsCompatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensionsKai Cui
 
Web components with Angular
Web components with AngularWeb components with Angular
Web components with AngularAna Cidre
 
Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.jsMatthew Beale
 
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Ontico
 
Angular 2.0 Routing and Navigation
Angular 2.0 Routing and NavigationAngular 2.0 Routing and Navigation
Angular 2.0 Routing and NavigationEyal Vardi
 
Upgrading from Angular 1.x to Angular 2.x
Upgrading from Angular 1.x to Angular 2.xUpgrading from Angular 1.x to Angular 2.x
Upgrading from Angular 1.x to Angular 2.xEyal Vardi
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Eliran Eliassy
 
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...Codemotion
 
Why Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebWhy Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebBryan Helmig
 
Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose worldFabio Collini
 

What's hot (20)

Workshop 17: EmberJS parte II
Workshop 17: EmberJS parte IIWorkshop 17: EmberJS parte II
Workshop 17: EmberJS parte II
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
 
Rails Best Practices
Rails Best PracticesRails Best Practices
Rails Best Practices
 
Workshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIWorkshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte II
 
Compatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensionsCompatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensions
 
Web components with Angular
Web components with AngularWeb components with Angular
Web components with Angular
 
Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.js
 
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
 
Kyiv.py #17 Flask talk
Kyiv.py #17 Flask talkKyiv.py #17 Flask talk
Kyiv.py #17 Flask talk
 
Angular 2.0 Routing and Navigation
Angular 2.0 Routing and NavigationAngular 2.0 Routing and Navigation
Angular 2.0 Routing and Navigation
 
Upgrading from Angular 1.x to Angular 2.x
Upgrading from Angular 1.x to Angular 2.xUpgrading from Angular 1.x to Angular 2.x
Upgrading from Angular 1.x to Angular 2.x
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
 
Angular 2.0 - What to expect
Angular 2.0 - What to expectAngular 2.0 - What to expect
Angular 2.0 - What to expect
 
My java file
My java fileMy java file
My java file
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
 
Angular2 - In Action
Angular2  - In ActionAngular2  - In Action
Angular2 - In Action
 
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
 
Why Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebWhy Task Queues - ComoRichWeb
Why Task Queues - ComoRichWeb
 
Flask Basics
Flask BasicsFlask Basics
Flask Basics
 
Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
 

Viewers also liked

Visualizing MVC, and an introduction to Giotto
Visualizing MVC, and an introduction to GiottoVisualizing MVC, and an introduction to Giotto
Visualizing MVC, and an introduction to Giottopriestc
 
Ruby For Web Development
Ruby For Web DevelopmentRuby For Web Development
Ruby For Web DevelopmentJames Thompson
 
Stages Of Programming Skill, From Freshman To Senior
Stages Of Programming Skill, From Freshman To SeniorStages Of Programming Skill, From Freshman To Senior
Stages Of Programming Skill, From Freshman To Seniorpriestc
 
Stashaway 1
Stashaway 1Stashaway 1
Stashaway 1priestc
 
Ruby In Enterprise Development
Ruby In Enterprise DevelopmentRuby In Enterprise Development
Ruby In Enterprise Developmentyelogic
 
The Kanye Quotient
The Kanye QuotientThe Kanye Quotient
The Kanye Quotientpriestc
 

Viewers also liked (7)

Visualizing MVC, and an introduction to Giotto
Visualizing MVC, and an introduction to GiottoVisualizing MVC, and an introduction to Giotto
Visualizing MVC, and an introduction to Giotto
 
Ruby For Web Development
Ruby For Web DevelopmentRuby For Web Development
Ruby For Web Development
 
Stages Of Programming Skill, From Freshman To Senior
Stages Of Programming Skill, From Freshman To SeniorStages Of Programming Skill, From Freshman To Senior
Stages Of Programming Skill, From Freshman To Senior
 
Stashaway 1
Stashaway 1Stashaway 1
Stashaway 1
 
Programação
ProgramaçãoProgramação
Programação
 
Ruby In Enterprise Development
Ruby In Enterprise DevelopmentRuby In Enterprise Development
Ruby In Enterprise Development
 
The Kanye Quotient
The Kanye QuotientThe Kanye Quotient
The Kanye Quotient
 

Similar to Models, controllers and views

using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'sAntônio Roberto Silva
 
Intoduction to Play Framework
Intoduction to Play FrameworkIntoduction to Play Framework
Intoduction to Play FrameworkKnoldus Inc.
 
Threads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSThreads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSTechWell
 
angularJs Workshop
angularJs WorkshopangularJs Workshop
angularJs WorkshopRan Wahle
 
AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014Ran Wahle
 
How to instantiate any view controller for free
How to instantiate any view controller for freeHow to instantiate any view controller for free
How to instantiate any view controller for freeBenotCaron
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Plataformatec
 
Asp.net MVC - Course 2
Asp.net MVC - Course 2Asp.net MVC - Course 2
Asp.net MVC - Course 2erdemergin
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010Fabien Potencier
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar SimovićJS Belgrade
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksMongoDB
 
Interoperable Component Patterns
Interoperable Component PatternsInteroperable Component Patterns
Interoperable Component PatternsMatthew Beale
 
Mvc interview questions – deep dive jinal desai
Mvc interview questions – deep dive   jinal desaiMvc interview questions – deep dive   jinal desai
Mvc interview questions – deep dive jinal desaijinaldesailive
 
MVC & SQL_In_1_Hour
MVC & SQL_In_1_HourMVC & SQL_In_1_Hour
MVC & SQL_In_1_HourDilip Patel
 
Re-Design with Elixir/OTP
Re-Design with Elixir/OTPRe-Design with Elixir/OTP
Re-Design with Elixir/OTPMustafa TURAN
 
Samsung WebCL Prototype API
Samsung WebCL Prototype APISamsung WebCL Prototype API
Samsung WebCL Prototype APIRyo Jin
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 

Similar to Models, controllers and views (20)

using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API's
 
Asp.net mvc
Asp.net mvcAsp.net mvc
Asp.net mvc
 
Intoduction to Play Framework
Intoduction to Play FrameworkIntoduction to Play Framework
Intoduction to Play Framework
 
Threads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSThreads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOS
 
angularJs Workshop
angularJs WorkshopangularJs Workshop
angularJs Workshop
 
Java script
Java scriptJava script
Java script
 
AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014
 
How to instantiate any view controller for free
How to instantiate any view controller for freeHow to instantiate any view controller for free
How to instantiate any view controller for free
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010
 
Asp.net MVC - Course 2
Asp.net MVC - Course 2Asp.net MVC - Course 2
Asp.net MVC - Course 2
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Interoperable Component Patterns
Interoperable Component PatternsInteroperable Component Patterns
Interoperable Component Patterns
 
Mvc interview questions – deep dive jinal desai
Mvc interview questions – deep dive   jinal desaiMvc interview questions – deep dive   jinal desai
Mvc interview questions – deep dive jinal desai
 
MVC & SQL_In_1_Hour
MVC & SQL_In_1_HourMVC & SQL_In_1_Hour
MVC & SQL_In_1_Hour
 
Re-Design with Elixir/OTP
Re-Design with Elixir/OTPRe-Design with Elixir/OTP
Re-Design with Elixir/OTP
 
Spring Web MVC
Spring Web MVCSpring Web MVC
Spring Web MVC
 
Samsung WebCL Prototype API
Samsung WebCL Prototype APISamsung WebCL Prototype API
Samsung WebCL Prototype API
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 

Recently uploaded

Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 

Recently uploaded (20)

Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 

Models, controllers and views

  • 1. The Three line MVC application and introducing Giotto
  • 2. Table on contents First part: Why high level code organization schemes are important Second part: All about MVC Third Part: Giotto!
  • 3. My experiences 1. Started web development in 2007 2. Wrote code without any kind of architectural pattern at all 3. This was very frustrating, but I didn't know any better 4. Realized it's taking too long to get stuff fixed and its not fun 5. Learned first hand that not using MVC is a pain
  • 5. Flightlogg.in' Was originally PHP (non-MVC) Now is django (mostly MVC) View: HTML/Javascript Controller: Standard HTTP GET/POST Model: Flight Storage and flight data analysis.
  • 7. Imagine... 1 app 1 django view, 9000 lines of code
  • 8. Imagine... We want to fix this. Refactor!! step 1: 1000 functions, 9 lines each
  • 9. Imagine... step 2: 100 classes, 10 functions each
  • 10. And then... App Models class class Views class class Controllers class class
  • 11.
  • 12. Overview 1. Models - The application 2. Controllers - The interface a. ties your application (model) to the outside world 3. Views - The presentation of the output to the user
  • 13. Models 1. Usually the biggest part of your application 2. Business Logic 3. Not just database tables 4. Should be completely controller independent
  • 14. Views 1. All about formatting output from model. 2. Templates/HTML 3. Serializers 4. Should be independent of any controllers (templates are portable)
  • 15. Controllers 1. How the data gets to and from the user 2. Apache, nginx, varnish, django middleware, mod_wsgi are all technically part of the controller. 3. What goes into my controller? a. High level Model code b. High level View code c. final interface level operations
  • 16. An example controller def new_flight_controller(request): total_time = request.POST['total_time'] landings = request.POST['landings'] user = request.user flight = Flight.new_flight(user, total_time, landings) try: flight.save() except: raise HttpResponseError("invalid flight data") return render_to_response( context={'flights': Flight.objects.filter(request.user)} template='flights.html')
  • 17. An example controller def new_flight_controller(request): total_time = request.POST['total_time'] landings = request.POST['landings'] Interface operations user = request.user flight = Flight.new_flight(user, total_time, landings) try: High level model code flight.save() except: raise HttpResponseError("invalid flight data") return render_to_response( context={'flights': Flight.objects.filter(request.user)} template='flights.html') High level view code
  • 18. Another example controller class NewFlightCommand(BaseCommand): option_list = BaseCommand.option_list + ( make_option('--total_time', '-t', dest='total_time'), make_option('--landings', '-l', dest='landings'), make_option('--user', '-u', dest='user') ) def handle(self, *args, **options): flight = Flight.new_flight(**options) try: flight.save() except: print "Invalid flight data" print "Flight saved!"
  • 19. Don't put non-controller code inside a controller! def to_decimal(input): """ >>> to_decimal('3:30') 3.5 >>> to_decimal('3.5') 3.5 >>> to_decimal('3:12') 3.2 """ This is not a controller function! Not high level model code, not high level view code, and not interface specific!!!
  • 20. This code is not controller code! def controller(request): total_time = to_decimal(request.GET['total_time']) # bad! landings = request.GET['landings'] user = request.user flight = Flight.new_flight(user, total_time, landings) try: flight.save() except: raise HttpResponseError("invalid flight data") return render_to_response( context={'flights': Flight.objects.filter(request.user)} template='flights.html')
  • 21. The three line MVC application! def mini_controller(request): return {total_time: request.GET['total_time'], landings: request.GET['landings'], user: request.user} def new_flight(request): args = mini_controller(request) flight = Flight.new_flight(*args).save() return render_to_response('view_flight.html', {'flight': flight})
  • 22. The MVC color-wheel Model Middleware ModelViews / Forms Controller View Context processors
  • 23. ModelViews 1. Projection of a Model (subclass) intended for use in a set of views 2. Atomic elements that should not hinder the 'real' view's ability to do its job.
  • 24. ModelViews class HTMLFlight(Flight): def as_tr(self): """ >>> HTMLFlight.objects.get(pk=234321).as_tr() '<tr id="flight_234321"><td class="total_time">3.5</td>... """ class JSONFlight(Flight): def as_json(self): """ >>> JSONFlight.objects.get(pk=56216).as_json() '{id: 56216, plane: {tailnumber: "N63NE", type: "SA-227"... """
  • 25. ModelView def list_flights_controller(request, format): if format == 'json': return JSONFlight, 'flights.json' elif format == 'html': return HTMLFlight, 'flights.html' def list_flights(request, format): Flight, view = list_flights_controller(request, format) flights = Flight.objects.filter(user=request.user) return render_to_response({'flights': flights}, view)
  • 26. ModelView flights.html: <table class="whatever"> {{ Flight.header }} {% for flight in flights %} {{ flight.as_tr }} {% endfor %} </table> flights.json: {user: {{ request.user }}, flights: {% for flight in flights %} {{ flight.as_json }}, {% endfor %} }
  • 27. Good models are easy to test class BaseFlightFailedTest(object): exc = Flight.InvalidFlightData def test(self): for kwargs in self.kwarg_set: self.assertRaises(Flight.new_flight(**kwargs), self.exc) class TotalGreatestTest(TestCase, BaseFlightFailedTest): exc = Flight.TotalMustBeGreatest kwarg_set = [{'total_time': '3:50', 'pic': 9.6}, {'total_time': 1.0, 'night': 2.3}] class NoNightTime(TestCase, BaseFlightFailedTest) kwarg_set = [{'total_time': 1, 'night': 0, 'night_landings': 5}]
  • 28. Tips: 1. Don't pass request objects into the model a. It couples your model to HTTP requests b. Models should only work with raw data 2. Try to avoid putting business logic into a controller a. It makes it hard to reuse models 3. Pass in only one model object to a view. a. if you have trouble doing this, your models may be wrong b. helps keep the templates reusable. 4. Make an attempt to re-write all your controllers to be exactly 3 lines.
  • 29. Giotto! - New python web development framework!! - Absolutely nothing has been started yet. - Doesn't let you violate MVC. - There should be one-- and preferably only one --obvious way to do it. - "MV" framework. (micro controllers) - Completely automatic urls - plugins for features - plugins for controller backends. (commandline, http-get, etc)
  • 30. Giotto Feature @interfaces('http-get', 'commandline') class ShowFlightsForUser(Feature): """ Show flights for a given user """ controller = {'user': Input.data.user} model = Flight.objects.show_for_user view = ShowFlights url for feature: {% http-get ShowFlightsForUser.html 59 %} -> Logbook.com/flights/ShowFlightsForUser.html?user=59
  • 31. Giotto Interfaces @interfaces('http-put', 'commandline') class NewFlight(Feature): """ Create a new flight """ controller = {'user': Input.data.user, 'total_time': Input.data... model = Logbook.Flight.create view = SingleFlight Using the feature: $ ./giotto.py logbook NewFlight --user=chris --total_time=3 ... or PUT /new_flight.json HTTP/1.1 user=chris&total_time=3 ...
  • 32. Giotto Models class Manager(models.Manager) def show_for_user(self, user): return self.filter(user=user) def create(self, *args, **kwargs): # logic goes here return Flight(**kwargs) class Flight(models.Model): attribute = models.Field() objects = Manager()
  • 33. Accessing features command line: $ ./giotto.py app feature format [args] http-get POST app.com/feature.format HTTP/1.1 [args] sms text "feature format [args]" to 3558526 The controller backend handles transporting data to/from the user
  • 34. Controllers handle everything for you @interfaces('http-get', 'commandline') class ShowRouteForFlight(Feature): """ Get the route for a single flight """ controller = Flight.id model = Flight.route view = SingleRouteView
  • 35. Giotto Views Take only a single model instance as the only context (obj) Views can return anything, as long as the controller backend knows how to handle it. templates make links to application features: <a href="{% url_get ShowFlightsForUser obj.user %}"> see {{ obj.user }}'s flights! </a>
  • 36. Giotto Views class SingleRouteView(View): def png(self, route): "Given a route, return as a png image" return image_file def kml(self, route): return kml_string def html(self, route): return jinja2.render({'obj': route}, 'route.html') {% http-get RouteForFlight.kml 36426 %} {% http-get RouteForFlight.html 36426 %} giotto logbook RouteForFlight png 36426 | file.png