On Wed, Sep 22, 2010 at 1:56 AM, klaasvanschel...@gmail.com < klaasvanschel...@gmail.com> wrote:
> Ok here it goes: I don't have a proper platform for my observations / > rants so I figured I'd try my luck here. Django has been my favorite > framework for developing web applications for about a year and a half, > so it comes from a position of love when I say that the Django app > really sucks as a level of abstraction. And I'm really looking for a > way out so any suggestions are much appreciated. A tl;dr is provided > below. > > Others have complained before me. Two particular ones worth mentioning > are: > http://www.scribd.com/doc/37113340/Why-Django-Sucks-and-How-we-Can-Fix-it > which claims that "Apps which provide models are inflexible" and > > http://www.mutualinformation.org/2010/03/why-i-switched-to-pylons-after-using-django-for-six-months/ > Both claim that the Django app provides the wrong level of > abstraction, neither goes in too much detail exactly why that is the > case. That's the question I'll attempt to answer. > > Before we can answer the question we must first set some reasonable > expectations for an "app". I'd say an app is a small package of > closely related features as they are presented to the user (in the > context of a web project) that can be easily modified/extended for any > given project. > > Examples of apps (in my own particular context): > * Dealing with customer information (a mini CRM). Adding, editing, > useful overviews. > * A small news app (Add, edit, overviews) > * Our own particular UserProfile app (editing, viewing others, > birthday calendars etc.) > * A small budgetting tool (creating budgets, see how much money has > been used) > * Logging time lines (for worked hours), searching them. > Wow! I guess your definition of an app and expectation of re-usuability from an app written by someone else is fairly high! We have built serveral news sites based on Django, and a lot of code gets rewritten everytime, because customer requirements are very different. We reuse 90% of code in every project, but 10% gets rewritten or gets writtenf fresh. I know there's a number of apps out there including ones written by people like me, which are grossly unusable. I guess that's primarily because its written by developers for a specific work, and when they threw it back into the wild, they did not pay enought attention tomake it really re-usuable. However there are quite a few exceptions, I completely agree with your views that with the way you write code with {% url in templates, and decorators, reusing the code is a pain. I had to scrap a project based on Pinax for the same reason, and then rewrite a mini scoial framework, because pinax is not customizable beyond a point. However my personal experience is that it's true for most platforms. There are always trade-offs and trade-ins when you use a platform. > I choose this definition for "app" because it is a very useful one in > the context of web projects. At least in my context it works like > this: we have a lot of customers with similar intranets and extranets. > Each one of them might want a particular subset of the various apps we > have "on the shelf". > > By the way: there's other things that can already be reused quite > well. Anything pure python for example. Or extensions to Django (extra > fields, extra context managers, middleware etc etc.) This is not my > concern, mainly because it already works well. > > One thing that deserves extra stress is that apss should be easily > extendable. Exactly the fact that every customer want something that > is slightly different from the next is how we're able to provide > value. (This is also the reason I like Django in the first place: > making stuff "your own way" is very easy). So: if no one want exactly > the same, extensibility is a major prerequisite for reusability. > > What are some typical things we want to do when extending (modifying) > an app for the context of a particular project? > * Deal with authorization in the context of the particular django > project > * Styling for the project > * Turn a subset of the functionality on or off for a given project (no > docs, no 'advanced features') > * Add one or more fields to one or more models and possibly related > edit pages, view pages forms etc > > Given this control flow let's try to do some of the typical > modifications mentioned above: > Authorization: > Django has a beautiful mechanism for authorization, which is using > decorators (@may_do_a_b_or_c) directly in the views.py. > Tempting, but will not be modifyable in any way once you lift the app. > (because the decorator will become tied to the view function). Other > mechanisms are not presented (in a standardized way). If anyone has > ideas about this I'd love to discuss them. > > Styling: > This actually works well, by providing sufficient amount of hooks in > the templates and extending. > > Turning functionality on and off: > This could be made to work by working with a 'url_parts.py' in the > reusable app, that provides different url_patterns for the various > subsets. So one for the CRUD, one for the docs, one for the simple > features and one for the advanced features. Our project's urls.py > would then simply include the right subset from this url_parts.py. I'm > not sure it's very pretty though. > > Extending models > This is the big one, for two reasons. > 1. You almost always want to do this (for any change to the app that > is reflected in the underlying data) > 2. It's pretty much impossible. > > Why is it impossible? > Firstly, /app/models.py is always discovered, so unless we make all > Models abstract, or we do not include "app" in settings.py, models are > created for syncdb and any related commands. > > Secondly, let's take a look at Django's control flow: > * urls.py matches and calls, > * possibly via a decorator > * a view in views.py, that may use any number of > * models, > * forms and > * templates > The "official" way to modify a reusable app for your particular app is > by making it available as a kwarg with proper default in the view, and > then customizing it from urls.py. > However, if you simply want to add one field to a much used object, > this solution implies passing around the object class (factory) > through your whole app. That's not very elegant. > The same goes for any other changes at a lower level. Say I want to > swap in a particular Form (not uncommon). Or reuse 90% of the views > from an app, but replace 10% of the alltogether. If those 10% are > referenced from {% url %} tags (or reverse in a view) we're screwed. > > By the way: where do modifications of apps go anyway? The reusable app > already goes into /appname. So the modification (presuming it warrants > a full directory) goes into /my_appname? If reusable apps are common, > this means my projects look like this: > /app_a > /app_b > /app_c > /my_app_a > /my_app_b > /my_app_c > > Solutions: > http://www.scribd.com/doc/37113340/Why-Django-Sucks-and-How-we-Can-Fix-it > mentions using factories "everwhere". Too bad the actual speech cannot > be heard at scribd because the slides are just a bit thin on details. > > settings.py > In my humble opinion a good app adds no settings to settings.py. The > problems with settings.py are mentioned in many places, suffice to say > it's basically a big global. Also: we're programmers, not configurars. > > For the models problem specifically I came up with this about 7 months > ago: > https://bitbucket.org/vanschelven/superglue/ (very much proof of > concept) > > Superglue works like this: > For any reusable app that uses it, models are to be defined abstract. > Then a magic method (glue) is to be called (from the apps models.py). > This magic method looks at settings.py (meh) and possibly extends the > model. At that point the extended, non-abstract model is made > available for the rest of the app. > I don't really like it yet, but it could be a start. > > Another possible way forward could be object oriented views, like > here: > http://djangosnippets.org/snippets/1009/ > > tl;dr > * Django Apps Suck. Your reply explaining why they don't is expected. > * Reuse of a lot of things doesn't suck. But the specific unit app, > meaning a bunch of models that can be modified and presented with > their model-specific features, is extremely hard to reuse. > * Apps are mostly hard to reuse because they are hard to reuse with > minor modifications (extensions). > * Using decorators on views to define authorization levels ties in > said authorization levels with the app (and makes it non-reusable) > * The hardest things to change are at the bottom of Django's call > chain. Deep inside the views, we find particular Models, Forms and > references to other views. > * Models are extra hard to change, because they are expected to be non- > abstract in the app. > * There is no logical separation (dir structure) between "a reusable > app" and "my modifications to a reusable app". > * Settings.py is not a solution (it is a problem), though I don't > bother to explain why. > * Some ideas for solutions exist, but this seems to be an open problem > in the Django world. > Correct me if I'm wrong. > > hope to hear from you, > Klaas van Schelven > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-us...@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com<django-users%2bunsubscr...@googlegroups.com> > . > For more options, visit this group at > http://groups.google.com/group/django-users?hl=en. > > -- Ramdas S +91 9342 583 065 -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.