I've seen enough great reusable packages for Django. I've also seen a lot of really bad packages and even have been forced to use bad apps in production, that you should really either fork or hack in a very strange way.
Some awesome packages: - South https://pypi.python.org/pypi/South - django-piston https://pypi.python.org/pypi/django-piston - django-reversion https://pypi.python.org/pypi/django-reversion - sentry https://pypi.python.org/pypi/sentry - django-dbtemplates https://pypi.python.org/pypi/django-dbtemplates Some of my own that in my concern are great and reusable: - django-dash https://pypi.python.org/pypi/django-dash - ska (see the contrib package for password-less authentication into Django) https://pypi.python.org/pypi/ska It's just a matter of making the app reusable and flexible enough to adapt modifications. On Tuesday, 21 September 2010 22:26:36 UTC+2, Klaas van Schelven 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. > > 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 unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To post to this group, send email to django-users@googlegroups.com. Visit this group at http://groups.google.com/group/django-users. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/6c0f9314-3d0e-48bc-a800-95a3c1ba62ad%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.