SlideShare une entreprise Scribd logo
1  sur  36
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

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
 

Tendances (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
 

En vedette

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
 

En vedette (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
 

Similaire à 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
 

Similaire à 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
 

Dernier

Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 

Dernier (20)

Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 

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