SlideShare une entreprise Scribd logo
1  sur  20
Télécharger pour lire hors ligne
Two Scoops of Django 
Ch 7. Function-and Class-Based Views 
Ch 8. Best Practices for Function-Based Views 
2014/11/04 
Michelle Leu @flywindy
Agenda 
Django Views 
FBVs v.s. CBVs 
Best practices for FBVs 
URL Namespaces 
Loose Coupling 
Summary
Django Views 
Django Views are functions 
y = f(x) # math 
HttpResponse = view(HttpRequest) # FBV 
HttpResponse = View.as_view(HttpRequest) # CBV
Django Views 
keep business logic out of Views 
model methods 
manger methods 
general utility helper function 
forms 
Business logic is the 
part of the program 
that encodes the real-world 
business rules 
that determine how 
data can be created, 
displayed, stored, and 
changed……. 
(From wikipedia)
FBVs (Function Based Views) 
Django 1.7 Tutorial Part 3 
# polls/views.py 
… 
from django.shortcuts import render 
from polls.models import Question 
def index(request): 
latest_question_list = Question.objects.all().order_by('-pub_date')[:5] 
context = {'latest_question_list': latest_question_list} 
return render(request, 'polls/index.html', context) 
def detail(request, question_id): 
question = get_object_or_404(Question, pk=question_id) 
return render(request, 'polls/detail.html', {'question': question}) 
def results(request, question_id): 
question = get_object_or_404(Question, pk=question_id) 
return render(request, 'polls/results.html', {'question': question})
CBVs (Class Based Views) 
Django 1.7 Tutorial Part 4 
# polls/views.py 
… 
from django.views import generic 
from polls.models import Question 
class IndexView(generic.ListView): 
class DetailView(generic.DetailView): 
model = Question 
template_name = 'polls/detail.html' 
class ResultsView(generic.DetailView): 
model = Question 
template_name = 'polls/results.html' 
template_name = 'polls/index.html' 
context_object_name = 'latest_question_list' 
def get_queryset(self): 
"""Return the last five published questions.""" 
return Question.objects.order_by('-pub_date')[:5]
CBVs v.s. FBVs
CBVs v.s. FBVs 
For new comer: FBVs 
For new project: CBVs 
For past project: FBVs for most views, CBVs 
only for views that need to be subclassed. 
Write custom 403, 404, and 500 error handlers: 
FBVs # root URLconf 
handler500 = 'mysite.views.my_custom_error_view'
Best practices for FBVs 
Pass HttpRequest Object 
Pass HttpResponse Object 
Decorators
Decorators 
simple decorator template 
# EXAMPLE 8.5 
import functools 
def decorator(view_func): 
@functools.wraps(view_func) 
def new_view_func(request, *args, **kwargs): 
# modify HttpRequest object here 
response = view_func(request, *args, **kwargs) 
# modify HttpResponse object here 
return response 
return new_view_func
Decorators 
# EXAMPLE 8.6 
# sprinkles/decorators.py 
from functools import wraps 
from . import utils 
def check_sprinkles(view_func): 
@wraps(view_func) 
def new_view_func(request, *args, 
**kwargs): 
# modify HttpRequest object here 
request = 
utils.can_sprinkle(request) 
# request.can_sprinkle 
response = view_func(request, 
*args, **kwargs) 
# modify HttpResponse object 
here 
return response 
return new_view_func 
# EXAMPLE 8.7 
# sprinkles/views.py 
... 
from .decorators import / 
check_sprinkles 
@check_sprinkles 
def sprinkle_detail(request, pk): 
sprinkle = 
get_object_or_404(Sprinkle, pk=pk) 
return render(request, 
"sprinkles/sprinkle_detail.html", 
{"sprinkle": sprinkle})
URL Namespaces 
allow you to uniquely reverse named URL patterns even if different 
applications use the same URL names. 
are specified using the ':' operator. For example, the main index page of the 
admin application is referenced using 'admin:index'. This indicates a 
namespace of 'admin', and a named URL of ‘index'. 
can also be nested. 
# EXAMPLE 7.3 
# urls.py at root of project 
from django.conf.urls import include, url 
urlpatterns += patterns('', 
url(r'^tastings/', include('tastings.urls', namespace='tastings')), 
) 
7.4 
tastings/views.py snippet 
…… 
class TasteUpdateView(UpdateView): 
model = Tasting 
def get_success_url(self): 
return reverse("tastings:detail", kwargs={"pk": self.object.pk})
URL Namespaces 
# EXAMPLE 7.5 
# tastings/detail.html snippet 
…… 
<ul> 
{% for tasting in tastings %} 
<li> 
<a href="{% url "tastings:detail" tasting.pk %}">{{ tasting.title }}</a> 
<small> 
(<a href="{% url "tastings:update" tasting.pk %}">update</a>) 
</small> 
</li> 
{% endfor %} 
<ul> 
……
Why URL Namespaces? 
Makes for shorter, more obvious and DRY URL 
names 
Increases interoperability with Third-party 
libraries 
Easier searches, upgrades, and refactors 
Allow for more app and template reverse tricks
Loose Coupling 
鬆散耦合 
相對於 緊密耦合(tight coupling) 
In computing and systems 
design a loosely coupled 
system is one in which each of 
its components has, or makes 
use of, little or no knowledge of 
the definitions of other separate 
components ….… 
(From wikipedia)
Loose Coupling 
# BAD EXAMPLE 7.1 
from django.conf.urls import patterns, 
url 
from django.views.generic import / 
DetailView 
from tastings.models import Tasting 
urlpatterns = patterns('', 
url(r'^(?P<pk>d+)/$', 
DetailView.as_view( 
model=Tasting, 
template_name='tastings/ 
detail.htm'), 
name='detail'), 
url(r'^(?P<pk>d+)/results/$', 
DetailView.as_view( 
model=Tasting, 
template_name='tastings/ 
results.html'), 
name='results'), 
) 
authentication︖?
Loose Coupling 
閃開,讓專業的來! 
# EXAMPLE 7.1 
# tastings/views.py 
from django.views.generic import / 
DetailView 
from tastings.models import Tasting 
class TasteDetailView(DetailView): 
model = Tasting 
class 
TasteResultsView(TasteDetailView): 
template_name = 'tastings/ 
results.html' 
# EXAMPLE 7.1 
# tastings/urls.py 
from django.conf.urls import patterns, 
url 
from . import views 
urlpatterns = patterns('', 
url(r'^(?P<pk>d+)/$', 
views.TasteDetailView.as_view(), 
name='detail'), 
url(r'^(?P<pk>d+)/results/$', 
views.TasteResultsView.as_view(), 
name='results'), 
) 
<app_label>/<model_name><template_name_suffix>.html -> tastings/tasting_detail.html
Summary 
Don’t Repeat Yourself. (DRY) 
Do one thing and do it well. 
Views should handle presentation logic. 
Less code is better, and keep it simple. 
Complex nested-if blocks are to be avoided.
References 
Classy Class-Based Views: http://ccbv.co.uk/ 
Django project 1.7 tutorial: https://docs.djangoproject.com/en/ 
1.7/intro/tutorial01/ 
Django project 1.7 - URL namespaces: https:// 
docs.djangoproject.com/en/1.7/topics/http/urls/#url-namespaces 
Django Girls 學習⼿手冊: http://djangogirlstaipei.gitbooks.io/ 
django-girls-taipei-tutorial/ 
two-scoops-of-django-1.6 issues: https://github.com/twoscoops/ 
two-scoops-of-django-1.6/issues?q=is%3Aopen+is%3Aissue
Two scoops of django 1.6  - Ch7, Ch8

Contenu connexe

Tendances

Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Django
fool2nd
 
Filtering data with D2W
Filtering data with D2W Filtering data with D2W
Filtering data with D2W
WO Community
 

Tendances (20)

Tango with django
Tango with djangoTango with django
Tango with django
 
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
Odoo Experience 2018 - Develop an App with the Odoo Framework
Odoo Experience 2018 - Develop an App with the Odoo FrameworkOdoo Experience 2018 - Develop an App with the Odoo Framework
Odoo Experience 2018 - Develop an App with the Odoo Framework
 
Advancing JavaScript with Libraries (Yahoo Tech Talk)
Advancing JavaScript with Libraries (Yahoo Tech Talk)Advancing JavaScript with Libraries (Yahoo Tech Talk)
Advancing JavaScript with Libraries (Yahoo Tech Talk)
 
Efficient Rails Test-Driven Development - Week 6
Efficient Rails Test-Driven Development - Week 6Efficient Rails Test-Driven Development - Week 6
Efficient Rails Test-Driven Development - Week 6
 
Flask intro - ROSEdu web workshops
Flask intro - ROSEdu web workshopsFlask intro - ROSEdu web workshops
Flask intro - ROSEdu web workshops
 
Introducere in web
Introducere in webIntroducere in web
Introducere in web
 
Sencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
Sencha Roadshow 2017: Modernizing the Ext JS Class System and ToolingSencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
Sencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
 
How to learn to build your own PHP framework
How to learn to build your own PHP frameworkHow to learn to build your own PHP framework
How to learn to build your own PHP framework
 
Staying Sane with Drupal (A Develper's Survival Guide)
Staying Sane with Drupal (A Develper's Survival Guide)Staying Sane with Drupal (A Develper's Survival Guide)
Staying Sane with Drupal (A Develper's Survival Guide)
 
React, Flux, ES6 and problems we met
React, Flux, ES6 and problems we metReact, Flux, ES6 and problems we met
React, Flux, ES6 and problems we met
 
Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Django
 
Django Architecture Introduction
Django Architecture IntroductionDjango Architecture Introduction
Django Architecture Introduction
 
Introduction to Plugin Programming, WordCamp Miami 2011
Introduction to Plugin Programming, WordCamp Miami 2011Introduction to Plugin Programming, WordCamp Miami 2011
Introduction to Plugin Programming, WordCamp Miami 2011
 
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
 
KAAccessControl
KAAccessControlKAAccessControl
KAAccessControl
 
Dynamic Business Processes using Automated Actions
Dynamic Business Processes using Automated ActionsDynamic Business Processes using Automated Actions
Dynamic Business Processes using Automated Actions
 
jQuery Tips Tricks Trivia
jQuery Tips Tricks TriviajQuery Tips Tricks Trivia
jQuery Tips Tricks Trivia
 
Filtering data with D2W
Filtering data with D2W Filtering data with D2W
Filtering data with D2W
 

Similaire à Two scoops of django 1.6 - Ch7, Ch8

A Basic Django Introduction
A Basic Django IntroductionA Basic Django Introduction
A Basic Django Introduction
Ganga Ram
 
WRStmlDSQUmUrZpQ0tFJ4Q_a36bc57fe1a24dd8bc5ba549736e406f_C2-Week2.pptx
WRStmlDSQUmUrZpQ0tFJ4Q_a36bc57fe1a24dd8bc5ba549736e406f_C2-Week2.pptxWRStmlDSQUmUrZpQ0tFJ4Q_a36bc57fe1a24dd8bc5ba549736e406f_C2-Week2.pptx
WRStmlDSQUmUrZpQ0tFJ4Q_a36bc57fe1a24dd8bc5ba549736e406f_C2-Week2.pptx
salemsg
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
Luka Zakrajšek
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
django_introduction20141030
django_introduction20141030django_introduction20141030
django_introduction20141030
Kevin Wu
 

Similaire à Two scoops of django 1.6 - Ch7, Ch8 (20)

Web development with django - Basics Presentation
Web development with django - Basics PresentationWeb development with django - Basics Presentation
Web development with django - Basics Presentation
 
Jsf presentation
Jsf presentationJsf presentation
Jsf presentation
 
A Minimalist’s Attempt at Building a Distributed Application
A Minimalist’s Attempt at Building a Distributed ApplicationA Minimalist’s Attempt at Building a Distributed Application
A Minimalist’s Attempt at Building a Distributed Application
 
A Basic Django Introduction
A Basic Django IntroductionA Basic Django Introduction
A Basic Django Introduction
 
WRStmlDSQUmUrZpQ0tFJ4Q_a36bc57fe1a24dd8bc5ba549736e406f_C2-Week2.pptx
WRStmlDSQUmUrZpQ0tFJ4Q_a36bc57fe1a24dd8bc5ba549736e406f_C2-Week2.pptxWRStmlDSQUmUrZpQ0tFJ4Q_a36bc57fe1a24dd8bc5ba549736e406f_C2-Week2.pptx
WRStmlDSQUmUrZpQ0tFJ4Q_a36bc57fe1a24dd8bc5ba549736e406f_C2-Week2.pptx
 
Raybiztech Guide To Backbone Javascript Library
Raybiztech Guide To Backbone Javascript LibraryRaybiztech Guide To Backbone Javascript Library
Raybiztech Guide To Backbone Javascript Library
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
 
DJ-06-Views-Templates.pptx
DJ-06-Views-Templates.pptxDJ-06-Views-Templates.pptx
DJ-06-Views-Templates.pptx
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
Jsf
JsfJsf
Jsf
 
Approaches to mobile site development
Approaches to mobile site developmentApproaches to mobile site development
Approaches to mobile site development
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
J2EE pattern 5
J2EE pattern 5J2EE pattern 5
J2EE pattern 5
 
Django
DjangoDjango
Django
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for Beginners
 
django_introduction20141030
django_introduction20141030django_introduction20141030
django_introduction20141030
 
Angular training - Day 3 - custom directives, $http, $resource, setup with ye...
Angular training - Day 3 - custom directives, $http, $resource, setup with ye...Angular training - Day 3 - custom directives, $http, $resource, setup with ye...
Angular training - Day 3 - custom directives, $http, $resource, setup with ye...
 
AngularJs-training
AngularJs-trainingAngularJs-training
AngularJs-training
 
CCCDjango2010.pdf
CCCDjango2010.pdfCCCDjango2010.pdf
CCCDjango2010.pdf
 
Rapid web application development using django - Part (1)
Rapid web application development using django - Part (1)Rapid web application development using django - Part (1)
Rapid web application development using django - Part (1)
 

Plus de flywindy (6)

Ready Programmer One
Ready Programmer OneReady Programmer One
Ready Programmer One
 
Django workshop homework 3
Django workshop homework 3Django workshop homework 3
Django workshop homework 3
 
Django 實戰 - 自己的購物網站自己做
Django 實戰 - 自己的購物網站自己做Django 實戰 - 自己的購物網站自己做
Django 實戰 - 自己的購物網站自己做
 
Two scoops of Django - Deployment
Two scoops of Django - DeploymentTwo scoops of Django - Deployment
Two scoops of Django - Deployment
 
Django best practices for logging and signals
Django best practices for logging and signals Django best practices for logging and signals
Django best practices for logging and signals
 
Two scoops of django Introduction
Two scoops of django IntroductionTwo scoops of django Introduction
Two scoops of django Introduction
 

Two scoops of django 1.6 - Ch7, Ch8

  • 1. Two Scoops of Django Ch 7. Function-and Class-Based Views Ch 8. Best Practices for Function-Based Views 2014/11/04 Michelle Leu @flywindy
  • 2. Agenda Django Views FBVs v.s. CBVs Best practices for FBVs URL Namespaces Loose Coupling Summary
  • 3. Django Views Django Views are functions y = f(x) # math HttpResponse = view(HttpRequest) # FBV HttpResponse = View.as_view(HttpRequest) # CBV
  • 4. Django Views keep business logic out of Views model methods manger methods general utility helper function forms Business logic is the part of the program that encodes the real-world business rules that determine how data can be created, displayed, stored, and changed……. (From wikipedia)
  • 5. FBVs (Function Based Views) Django 1.7 Tutorial Part 3 # polls/views.py … from django.shortcuts import render from polls.models import Question def index(request): latest_question_list = Question.objects.all().order_by('-pub_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context) def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question}) def results(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/results.html', {'question': question})
  • 6. CBVs (Class Based Views) Django 1.7 Tutorial Part 4 # polls/views.py … from django.views import generic from polls.models import Question class IndexView(generic.ListView): class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' class ResultsView(generic.DetailView): model = Question template_name = 'polls/results.html' template_name = 'polls/index.html' context_object_name = 'latest_question_list' def get_queryset(self): """Return the last five published questions.""" return Question.objects.order_by('-pub_date')[:5]
  • 8. CBVs v.s. FBVs For new comer: FBVs For new project: CBVs For past project: FBVs for most views, CBVs only for views that need to be subclassed. Write custom 403, 404, and 500 error handlers: FBVs # root URLconf handler500 = 'mysite.views.my_custom_error_view'
  • 9. Best practices for FBVs Pass HttpRequest Object Pass HttpResponse Object Decorators
  • 10. Decorators simple decorator template # EXAMPLE 8.5 import functools def decorator(view_func): @functools.wraps(view_func) def new_view_func(request, *args, **kwargs): # modify HttpRequest object here response = view_func(request, *args, **kwargs) # modify HttpResponse object here return response return new_view_func
  • 11. Decorators # EXAMPLE 8.6 # sprinkles/decorators.py from functools import wraps from . import utils def check_sprinkles(view_func): @wraps(view_func) def new_view_func(request, *args, **kwargs): # modify HttpRequest object here request = utils.can_sprinkle(request) # request.can_sprinkle response = view_func(request, *args, **kwargs) # modify HttpResponse object here return response return new_view_func # EXAMPLE 8.7 # sprinkles/views.py ... from .decorators import / check_sprinkles @check_sprinkles def sprinkle_detail(request, pk): sprinkle = get_object_or_404(Sprinkle, pk=pk) return render(request, "sprinkles/sprinkle_detail.html", {"sprinkle": sprinkle})
  • 12. URL Namespaces allow you to uniquely reverse named URL patterns even if different applications use the same URL names. are specified using the ':' operator. For example, the main index page of the admin application is referenced using 'admin:index'. This indicates a namespace of 'admin', and a named URL of ‘index'. can also be nested. # EXAMPLE 7.3 # urls.py at root of project from django.conf.urls import include, url urlpatterns += patterns('', url(r'^tastings/', include('tastings.urls', namespace='tastings')), ) 7.4 tastings/views.py snippet …… class TasteUpdateView(UpdateView): model = Tasting def get_success_url(self): return reverse("tastings:detail", kwargs={"pk": self.object.pk})
  • 13. URL Namespaces # EXAMPLE 7.5 # tastings/detail.html snippet …… <ul> {% for tasting in tastings %} <li> <a href="{% url "tastings:detail" tasting.pk %}">{{ tasting.title }}</a> <small> (<a href="{% url "tastings:update" tasting.pk %}">update</a>) </small> </li> {% endfor %} <ul> ……
  • 14. Why URL Namespaces? Makes for shorter, more obvious and DRY URL names Increases interoperability with Third-party libraries Easier searches, upgrades, and refactors Allow for more app and template reverse tricks
  • 15. Loose Coupling 鬆散耦合 相對於 緊密耦合(tight coupling) In computing and systems design a loosely coupled system is one in which each of its components has, or makes use of, little or no knowledge of the definitions of other separate components ….… (From wikipedia)
  • 16. Loose Coupling # BAD EXAMPLE 7.1 from django.conf.urls import patterns, url from django.views.generic import / DetailView from tastings.models import Tasting urlpatterns = patterns('', url(r'^(?P<pk>d+)/$', DetailView.as_view( model=Tasting, template_name='tastings/ detail.htm'), name='detail'), url(r'^(?P<pk>d+)/results/$', DetailView.as_view( model=Tasting, template_name='tastings/ results.html'), name='results'), ) authentication︖?
  • 17. Loose Coupling 閃開,讓專業的來! # EXAMPLE 7.1 # tastings/views.py from django.views.generic import / DetailView from tastings.models import Tasting class TasteDetailView(DetailView): model = Tasting class TasteResultsView(TasteDetailView): template_name = 'tastings/ results.html' # EXAMPLE 7.1 # tastings/urls.py from django.conf.urls import patterns, url from . import views urlpatterns = patterns('', url(r'^(?P<pk>d+)/$', views.TasteDetailView.as_view(), name='detail'), url(r'^(?P<pk>d+)/results/$', views.TasteResultsView.as_view(), name='results'), ) <app_label>/<model_name><template_name_suffix>.html -> tastings/tasting_detail.html
  • 18. Summary Don’t Repeat Yourself. (DRY) Do one thing and do it well. Views should handle presentation logic. Less code is better, and keep it simple. Complex nested-if blocks are to be avoided.
  • 19. References Classy Class-Based Views: http://ccbv.co.uk/ Django project 1.7 tutorial: https://docs.djangoproject.com/en/ 1.7/intro/tutorial01/ Django project 1.7 - URL namespaces: https:// docs.djangoproject.com/en/1.7/topics/http/urls/#url-namespaces Django Girls 學習⼿手冊: http://djangogirlstaipei.gitbooks.io/ django-girls-taipei-tutorial/ two-scoops-of-django-1.6 issues: https://github.com/twoscoops/ two-scoops-of-django-1.6/issues?q=is%3Aopen+is%3Aissue