On Tuesday, June 5, 2012 at 9:29 AM, Albert O'Connor wrote: > Class Based View are awesome, except the ones which are built in? > >
Both the Built in Generic Class Based Views, and Class Based Views in general are great. Generic Class Based Views are not awesome when your view is not generic. > > I agree, as has been suggested, that if you make a really flat class > based views like the admin itself, you can gain some benefits, but I > still think those benefits are heavily tied to assumptions one can > make in a specific problem space. Keeping the ability to create a > Class Based View has value, but it is up to to the people who like > them to show the rest of us how they can be used with out creating > more problems then they solve, and just because they exist doesn't > mean they should be used more than they are. Apparently when it comes > to generic class based view they should be used less. > > The typical FBV that i've personally witnessed ends up being one large chunk of code where it's both impossible to reuse, but slightly differently, in a way that the original view didn't give you, and impossible to test small "units" of functionality. My best guesses as to why most people tend to write this way is because people like their views to be "one unit". For function based views that unit is one function and for class based views that unit is one class. The difference then lies in that within a class it is very easy to have multiple "sub units" (methods) that can each be dedicated to one purpose, and can easily be tested independently. Outside of the testing benefits, you now have a view where you can easily modify one "sub unit" without having to reach in and rewrite part of the view. An example would be, with the generic views, it's the pattern to have a "get_queryset" method which returns the queryset that the view will work off of. With a simple Mixin of:: class UserMixin(object): user_field_name = "user" def get_queryset(self, *args, **kwargs): qs = super(UserMixin, self).get_queryset(*args, **kwargs) qs = qs.filter(**{self.user_field_name: self.request.user if self.request.user.is_authenticated() else None}) return qs We now have the ability to "reach" into, and add filtering by the currently logged in user to any view that uses the get_queryset method in this way. This means that I could write a view that returns all of the "Widgets" in a system, and by simply adding this Mixin to the view, create a second view that lists all of "my" widgets. In order to do this with FBV's i'd either need to modify the existing FBV to accept a parameter that says if it should filter by logged in user or not or copy/paste the code into a new FBV. These options can be acceptable, especially when you control the code where those views come from. However if you do not control that code (if it for instance, comes from Django or comes from an external library) now you have the ability to really make those kinds of tweaks. > > Albert > > On Tue, Jun 5, 2012 at 9:14 AM, Donald Stufft <donald.stu...@gmail.com > (mailto:donald.stu...@gmail.com)> wrote: > > On Tuesday, June 5, 2012 at 9:05 AM, Albert O'Connor wrote: > > > > My feeling is that though some people might have uses for CBV, we > > shouldn't be suggesting that developers should prefer CBV to function > > based views. When it comes to maintainability, FBV are better, and I > > would agree that they are more Pythonic. > > > > When I tried to use CBV, I found the inheritance semantics lead to > > unexpected results when composing mixins. I wanted to spend my time > > creating web apps and not debugging to figure what 3 lines of glue > > code I would have to write in the correct overridden method to make > > CBV work for me in my usecase. At the time I felt of have a list of > > say context providers would have made more sense than mixins. > > > > Don't confuse the current Generic Class Based Views with Class Based > > Views in general. In almost every case Class Based Views are a net win, > > it's the generic views that are often the incorrect choice (as it makes > > sense, > > if what your view is doing isn't generic, then a Generic view isn't what you > > need). > > > > > > If people have uses for CBV, they should be available, but advocating > > that more builtin or contrib views should be made class based is > > something I would be against personally, unless it really made sense > > in a specific use case. > > > > Albert O'Connor > > > > On Tue, Jun 5, 2012 at 2:02 AM, Marc Tamlyn <marc.tam...@gmail.com > > (mailto:marc.tam...@gmail.com)> wrote: > > > > There is a plan to do some work on the docs at the djangocon sprints - in > > particular trying to get some examples of when you 'could' and when you > > 'should not' use the generic CBVs. > > > > With regards to Zach's point about TDD testing - some of that may simply be > > familiarity. I don't know about you but it would have been very difficult > > for me to get into successfully TDDing a functional view until I'd written > > several dozen views and knew what the pattern is. You can still test the CBV > > top to bottom, exactly as you would with a function based view. Yes there > > may be some shift to conventions, but that will come with familiarity. > > > > I think part of the important difference is that when you look at a CBV for > > the purposes of unit testing it, you feel very quickly that you should be > > testing the individual methods. This is actually really nice and gives a lot > > more branch-coverage without rerunning the same 4 database queries every > > time for variables which aren't used. Without CBVs a complex view can easily > > extend over 50 or so lines, whereas it's more natural to split this up and > > test the sections independently with a Class based system. I know in general > > we should be 'writing less view code' and pushing the logic elsewhere, but > > that depends on what that logic is - for example the view layer needs to > > decide whether to return JSON or HTML depending on certain headers in the > > request, and that is more easily testable as an overridden render to > > response method than as the last 4 lines of a 50 line view. > > > > Marc > > > > -- > > You received this message because you are subscribed to the Google Groups > > "Django developers" group. > > To view this discussion on the web visit > > https://groups.google.com/d/msg/django-developers/-/VZsGxxTYyoIJ. > > > > To post to this group, send email to django-developers@googlegroups.com > > (mailto:django-developers@googlegroups.com). > > To unsubscribe from this group, send email to > > django-developers+unsubscr...@googlegroups.com > > (mailto:django-developers+unsubscr...@googlegroups.com). > > For more options, visit this group at > > http://groups.google.com/group/django-developers?hl=en. > > > > > > > > > > -- > > > > <><><>< Albert O'Connor - amjoc...@gmail.com (mailto:amjoc...@gmail.com) > > > > albertoconnor.ca | wildernesslabs.ca | watpy.ca > > > > -- > > You received this message because you are subscribed to the Google Groups > > "Django developers" group. > > To post to this group, send email to django-developers@googlegroups.com > > (mailto:django-developers@googlegroups.com). > > To unsubscribe from this group, send email to > > django-developers+unsubscr...@googlegroups.com > > (mailto:django-developers+unsubscr...@googlegroups.com). > > For more options, visit this group at > > http://groups.google.com/group/django-developers?hl=en. > > > > > > -- > > You received this message because you are subscribed to the Google Groups > > "Django developers" group. > > To post to this group, send email to django-developers@googlegroups.com > > (mailto:django-developers@googlegroups.com). > > To unsubscribe from this group, send email to > > django-developers+unsubscr...@googlegroups.com > > (mailto:django-developers+unsubscr...@googlegroups.com). > > For more options, visit this group at > > http://groups.google.com/group/django-developers?hl=en. > > > > > > > -- > > <><><>< Albert O'Connor - amjoc...@gmail.com (mailto:amjoc...@gmail.com) > > albertoconnor.ca | wildernesslabs.ca | watpy.ca > > -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To post to this group, send email to django-developers@googlegroups.com > (mailto:django-developers@googlegroups.com). > To unsubscribe from this group, send email to > django-developers+unsubscr...@googlegroups.com > (mailto:django-developers+unsubscr...@googlegroups.com). > For more options, visit this group at > http://groups.google.com/group/django-developers?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.