The document discusses function-based views (FBVs) and class-based views (CBVs) in Django. It recommends using CBVs for new projects and FBVs for existing projects that only need to subclass some views. The document also provides best practices for FBVs, such as keeping business logic out of views and using decorators. It emphasizes loose coupling between URLs and views for better maintainability.
1 of 20
Downloaded 27 times
More Related Content
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)
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
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(/slideshow/two-scoops-of-django-16-ch7-ch8/41108153/r&)),
)
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})
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
柊骼栽
豢 o畜骼栽(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(/slideshow/two-scoops-of-django-16-ch7-ch8/41108153/r&)/$',
DetailView.as_view(
model=Tasting,
template_name='tastings/
detail.htm'),
name='detail'),
url(/slideshow/two-scoops-of-django-16-ch7-ch8/41108153/r&)/results/$',
DetailView.as_view(
model=Tasting,
template_name='tastings/
results.html'),
name='results'),
)
authentication?
17. Loose Coupling
W_I議蹌
# 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(/slideshow/two-scoops-of-django-16-ch7-ch8/41108153/r&)/$',
views.TasteDetailView.as_view(),
name='detail'),
url(/slideshow/two-scoops-of-django-16-ch7-ch8/41108153/r&)/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.