SlideShare uma empresa Scribd logo
1 de 36
Baixar para ler 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

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Destaque

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
 

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

Semelhante a 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
 

Semelhante a 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
 

Último

Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
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
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
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
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
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
 
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
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
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
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 

Último (20)

Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
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...
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
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...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
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
 
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
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
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
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 

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