Skip to content

Instantly share code, notes, and snippets.

@spookylukey
Last active January 11, 2019 02:28
Show Gist options
  • Save spookylukey/54f248e7cc1dc5f998b1456b4b601a0f to your computer and use it in GitHub Desktop.
Save spookylukey/54f248e7cc1dc5f998b1456b4b601a0f to your computer and use it in GitHub Desktop.
# If it's complex, Django's Generic CBVs will probably
# make your life harder. And if it's simple, they probably
# will too.
# Before:
from django.views import generic
class ReportPDFDetailView(generic.DetailView):
model = DesignerReport
def get_queryset(self):
return self.request.user.designer.reports.filter(is_approved=True)
def get(self, request, *args, **kwargs):
self.object = self.get_object()
report = self.object
download_filename = '%s_%i-%i.pdf' % (report.designer.name, report.month_index, report.year)
return internal_redirect_response(report.pdf_report, download_filename)
# After:
from django.shortcuts import get_object_or_404
def report_detail_view_pdf(request, pk=None):
report = get_object_or_404(request.user.designer.reports.filter(is_approved=True),
pk=pk)
download_filename = '%s_%i-%i.pdf' % (report.designer.name, report.month_index, report.year)
return internal_redirect_response(report.pdf_report, download_filename)
# Notes:
#
# * Yes, the ```model = DesignerReport`` line in the ‘before’ is unnecessary, but that's
# the way it was written. The indirection of CBVs discourages comprehension and
# encourages cargo-culting.
#
# * In a similar way, ``self.object = self.get_object()``, is also unnecessary,
# but it's clearly been added by someone who sensibly doesn't want to break
# anything. You never know what other things a CBV is doing that you mustn't
# break.
#
# * And then, the `report = self.object` line, again unnecessary strictly
# speaking, was clearly a helpful addition for the sake of clarity regarding
# what type of object we're dealing with. Generic CBV methods are incredibly
# unhelpfully named, because they are so generic.
#
# The rewritten version using a function can avoid all of this. In addition,
# it's massively simpler, clearer, and easier to reason about.
@SaurabhGoyal
Copy link

@spookylukey In my opinion, It's about the de-coupling of various parts of the flow for better extension and customisation at modular level of those parts. Ofcourse that comes with overhead of learning how it has been done so, but it's worth it when things start getting big and complex.

For ex.- In the above <10 line code, you may be tempted to think that FBV is shorter and better, but when the logic becomes complex and big (let's say ~50 lines), you'll thank the modular control CBVs provide every second of development.

Just my personal perception.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment