Why I don't like class-based generic views » commentshttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/2014-11-22T09:50:47.302571-08:00Ivan Sagalaev on programming and web developmenthttp://softwaremaniacs.org/media/sm_org/style/photo.jpgjetbird на "Why I don't like class-based generic views"
2014-11-22T09:50:47.302571-08:00jetbirdhttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-494325I am learning generic views and it has been a painful experience so far. The official documentation about them is bad.
<p>I am learning generic views and it has been a painful experience so far. The official documentation about them is bad.Andrey Popp на "Why I don't like class-based generic views"
2011-10-10T00:39:00.456702-07:00Andrey Popphttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-99615@coffeesnake Yeah, there's indeed some preference to OOP approach over the functional one in Python, not sure why. For instance in Scala functional approach is considered much more clean and robust way than writing imperative OO-code and those who prefer class abstractions over functional ones are usually considered as newbies...
<p>@coffeesnake</p>
<blockquote>
<p>Yeah, there's indeed some preference to OOP approach over the functional one in Python, not sure why. For instance in Scala functional approach is considered much more clean and robust way than writing imperative OO-code and those who prefer class abstractions over functional ones are usually considered as newbies in Scala community :)</p>
</blockquote>
<p>You seems to oppose FP to OOP, but I think this is wrong. FP is about being referentially transparent and OOP is about encapsulation. Please note I'm not saying FP langs don't have encapsulation, they are, but usually via other techniques, not OOP.</p>
<p>@Иван Сагалаев</p>
<p>You're definitely right, classes are essentially sets of related functions, nothing more. Anything you can do with classes you can also achieve by using functions in Python. But classes still exist in the language for the reason — they capture useful pattern named encapsulation.</p>
<p>Consider a function which is parametrized over some function which do filtering on database results:</p>
<pre><code>def func(filter_func):
pass
</code></pre>
<p>Now something has changed and you want also to parametrize your function over some another function which do grouping of database results:</p>
<pre><code>def func(filter_func, group_func):
pass
</code></pre>
<p>Now things get interesting — you need to change every <strong>func</strong> call to provide additional argument... and that's every time you add more parameters to your <strong>func</strong>. Another solution is to pass all functions as single argument — dictionary:</p>
<pre><code>def func(funcs):
filter_func = funcs["filter_func"]
group_func = funcs["group_func"]
...
</code></pre>
<p>But that's exactly the same as define you <strong>func</strong> being method in class and have parametrized over other methods:</p>
<pre><code>class Func(object):
def __call__(self):
filter_func = self.filter
group_func = self.group
...
</code></pre>
<p>This also helps in usual case of <strong>func</strong>'s params being closely related to each other — you define them together in single class definition and what's more important you can't mix params irrelevant to each other in client code.@coffeesnake на "Why I don't like class-based generic views"
2011-10-09T08:25:31.095094-07:00@coffeesnakehttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-99568Yeah, there's indeed some preference to OOP approach over the functional one in Python, not sure why. For instance in Scala functional approach is considered much more clean and robust way than writing imperative OO-code and those who prefer class abstractions over functional ones are usually considered as newbies in...
<p>Yeah, there's indeed some preference to OOP approach over the functional one in Python, not sure why. For instance in Scala functional approach is considered much more clean and robust way than writing imperative OO-code and those who prefer class abstractions over functional ones are usually considered as newbies in Scala community :) That's huge contrast comparing to Python which is really strange cuz Python features first-class functions and certain syntax sugar like decorators.</p>
<p>Looks like the only reason is Python's poor syntax for lambdas. People would probably use much more of FP in Python if they'd have some nicer way to define multiline anonymous functions inline. I mean the language is powerful enough but its syntax really encourages imperative style/OO-approach.andrew@amccloud.com на "Why I don't like class-based generic views"
2011-10-07T16:30:54.944528-07:00andrew@amccloud.comhttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-99423Иван Сагалаев: Yes MRO can bite you in the ass sometimes. Yes you can chain multiple functions with a slew of arguments to override behavior. Yes "generic" class-based views add some sort of boilerplate. Could you provide an instance where the boilerplate gets in your way and causes you to...
<p>Иван Сагалаев:</p>
<p>Yes MRO can bite you in the ass sometimes. Yes you can chain multiple functions with a slew of arguments to override behavior. Yes "generic" class-based views add some sort of boilerplate. Could you provide an instance where the boilerplate gets in your way and causes you to write more code or gets in your way? I've never had this issue and i've done some pretty radical things with class-based views like rendering to an api that interacts with phones. <a href="https://github.com/amccloud/django-tropo-webapi/blob/master/example/opengate/views.py">https://github.com/amccloud/django-tropo-webapi/blob/master/example/opengate/views.py</a>Ivan Sagalaev на "Why I don't like class-based generic views"
2011-10-07T15:46:08.819007-07:00Ivan Sagalaevhttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-99417I was expecting these :-) andrew@amccloud.com: Your language and category filtering code must be duplicated across all your views. This argument may work for one view but as soon as you have a project or app with 10+ views you wouldn't want this boilerplate mess in every view. Volodymyr Sergeyev:...
<p>I was expecting these :-)</p>
<p><em>andrew@amccloud.com</em>:</p>
<blockquote>
<p>Your language and category filtering code must be duplicated across all your views. This argument may work for one view but as soon as you have a project or app with 10+ views you wouldn't want this boilerplate mess in every view.</p>
</blockquote>
<p><em>Volodymyr Sergeyev</em>:</p>
<blockquote>
<p>Classes has one thing functions missing - inheritance. So you can reuse class Category() later (maybe with overiden methods/data).</p>
</blockquote>
<p>I already mentioned in the post, in passing, that in terms of code reuse functional and class paradigms are equivalent. I'm not going to write some sort of a formal proof here but I'll try my best to explain it…</p>
<p>A function, at its essence, is the abstraction of logic that can be reused elsewhere — nothing else. A method of a class is simply a function that has an implicit first argument (not that implicit in Python). This makes class methods a <em>specialized kind</em> of functions meaning that functional abstraction is actually more flexible than class-based. An instance of a class is much the same as a function with variables bound in a closure.</p>
<p>Inheritance is a fancy mechanism of method lookup that makes it possible to override only some of your methods. It implements the idea that descendant objects share a common semantics that is expressed with common method names. In a functional world you just have differently named functions that you can call freely from each other. Again, inheritance establishes <em>specialized rules</em> of naming and calling functions that makes class hierarchies less flexible than functional call graphs.</p>
<p><a href="https://gist.github.com/1415cf6300f07b9bc568">Andrew's example</a> shows this very well. Each part of the code that can be reused is represented by a mixin. And the final view just uses them all. All this can be easily expressed with functions:</p>
<pre><code>def translate(language):
# ...
def get_category(slug):
# ...
def filter_category(*args):
# ...
def view(request, language, slug):
translate(language)
return object_list(filter_category(get_category(slug)), PAGINATE_BY)
</code></pre>
<p>Having all those words inside the view — "translate", "filter_category", "get_category" — is the equivalent of listing mixin names in bases. But without having to think about the MRO :-). </p>
<p>If necessary this functional code can be made more generic. For example, <code>translate</code> can be a decorator and would dig for language parameter by itself. I don't have it in my code because <code>translation.activate(language or 'ru')</code> is not really worth shortening to <code>@translate</code>. And <code>object_list</code> can be a function with <code>PAGINATE_BY</code> as the default value for an argument. This is how I have it in my code right now because there are about five views using it. The outcome is the same as in a class code: <code>PAGINATE_BY</code> is present in the code only once, I don't repeat it.</p>
<p>My point is that class-based code adds boilerplate that can only be tolerated if you have many places to use it while functions are good for both ends of the simple—complex spectrum. The only real purpose of classes, as Malcolm wrote earlier, is to build DSLs. It's just so happened that this particular DSL of Django's generic views didn't work for my app (though it did work for one of my other apps).</p>
<p>Further (lazy) reading: <a href="http://mitpress.mit.edu/sicp/">SICP</a>, <a href="http://www.paulgraham.com/reesoo.html">Paul Graham on Object Orientation</a>.</p>
<p>P.S. BTW, I blame universities for continuing to plant the misconception of classes being more powerful than functions. It's notoriously hard to overcome.Volodymyr Sergeyev на "Why I don't like class-based generic views"
2011-10-07T10:29:08.421930-07:00Volodymyr Sergeyevhttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-99390Classes has one thing functions missing - inheritance. So you can reuse class Category() later (maybe with overiden methods/data). Imho, as always.
<p>Classes has one thing functions missing - inheritance. So you can reuse class Category() later (maybe with overiden methods/data). </p>
<p>Imho, as always.andrew@amccloud.com на "Why I don't like class-based generic views"
2011-10-07T10:20:00.502621-07:00andrew@amccloud.comhttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-99389From Reddit: I'd have to disagree with this article. It misses a major point of class-based (generic) views. Your language and category filtering code must be duplicated across all your views. This argument may work for one view but as soon as you have a project or app with 10+...
<p>From Reddit:</p>
<p>I'd have to disagree with this article. It misses a major point of class-based (generic) views. Your language and category filtering code must be duplicated across all your views. This argument may work for one view but as soon as you have a project or app with 10+ views you wouldn't want this boilerplate mess in every view.</p>
<p>This code needs to be separated (mixins are a good choice for this) so that it can be mixed and matched in multiple views at a whim.</p>
<p><a href="https://gist.github.com/1415cf6300f07b9bc568">https://gist.github.com/1415cf6300f07b9bc568</a> (untested but i'm using something very similar)</p>
<p>As you can see the final view boils down to 3 lines of code, the rest of your views will also end up a very low LOC. Your code may be shorter in one view but as your codebase scales to multiple views properly utilized class-based views will not only reduce your line count, it will reduce the chances of error.John DeRosa на "Why I don't like class-based generic views"
2011-10-07T08:40:02.833118-07:00John DeRosahttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-99380+1! I wrote about this (but not as eloquently as you did) in my own blog a few months back. (http://seeknuance.com/2011/05/28/i-dont-like-django-class-based-generic-views/) I agree with the intent, but between the extra coding you need to make them work, and the documentation's paucity, they're not fun at all. I still don't use...
<p>+1! I wrote about this (but not as eloquently as you did) in my own blog a few months back. (<a href="http://seeknuance.com/2011/05/28/i-dont-like-django-class-based-generic-views/">http://seeknuance.com/2011/05/28/i-dont-like-django-class-based-generic-views/</a>) I agree with the intent, but between the extra coding you need to make them work, and the documentation's paucity, they're not fun at all. I still don't use them.Dean на "Why I don't like class-based generic views"
2011-10-07T07:43:31.069228-07:00Deanhttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-99371Definitely agree... I'm relatively new to Django and generic views made no sense to me coming from other frameworks (Grails and Rails). I'm glad to see I'm not the only one...
<p>Definitely agree... I'm relatively new to Django and generic views made no sense to me coming from other frameworks (Grails and Rails). I'm glad to see I'm not the only one...Sergey Tkachuk на "Why I don't like class-based generic views"
2011-10-06T21:46:38.990969-07:00Sergey Tkachukhttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-99301I totally agree. Class-based generic views is the ugliest thing in django.
<p>I totally agree. Class-based generic views is the ugliest thing in django.Malcolm Tredinnick на "Why I don't like class-based generic views"
2011-10-06T21:24:30.292928-07:00Malcolm Tredinnickhttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-99298Definitely agree. A long-time complaint of mine about trying to write domain specific languages is that now the developer has to learn a second language and unless it's a HUGE win to do so or the language is absolutely tiny, the extra abstraction is making things harder. Class-based views are...
<p>Definitely agree. A long-time complaint of mine about trying to write domain specific languages is that now the developer has to learn a second language and unless it's a HUGE win to do so or the language is absolutely tiny, the extra abstraction is making things harder. Class-based views are a DSL, in effect: they are trying to remove the need to write a view by saying you "only" have to fit the bits in your code that are different to the framework pattern, so the language is a pattern language. But people's constant wish for Yet Another Lever and Shiny Button(tm) has led to something that isn't a huge difference over just writing a view in the first place. Developers already have a nicely configurable interface for writing views: it's called Python.Vee на "Why I don't like class-based generic views"
2011-10-06T20:48:30.224632-07:00Veehttps://softwaremaniacs.org/blog/2011/10/06/class-based-generic-views/en/#comment-99295+1. Ну, и, "We'll never know if they would be prettier..." "... functions just make more sense. I, for one, simply ... and everything just worked." Oh, и в школе учили что начинать sentence с "Probably" или "And" неположено. :D
<p>+1.</p>
<p>Ну, и,</p>
<p>"We'll never know if they would be prettier..."</p>
<p>"... functions just make more sense. I, for one, simply ... and everything just worked."</p>
<p>Oh, и в школе учили что начинать sentence с "Probably" или "And" неположено.</p>
<p>:D