Package: django-fnd8n
The ProblemDjangoclearly defines the following paradigms (amongst others):Object-Relational Mapping (ORM) via ModelsRequest Routing via URLsData Binding via FormsRequest-to-Response Mapping via ViewsData Presentation via TemplatesWhile this explicit control over the design and function of each component is
optimal for many use cases, one could argue that it runs afould of Django’s
most desirable design principle: “Don’t Repeat Yourself” (DRY).  More
to the point, while Django ships with an admin app that most new users rave
about, there is no obvious way to expose a front-end without a fair amount of
work (especially when auth or comprehension of model interrelationships is
desired) that could be simplified greatly if there was a central class through
which those interrelationships were managed.Many approaches set out to solve this through class methods on the Models or
their Managers, but that runs counter to the spirit of segregating the Model
(intended to be a representation of the state of the DB) from logic (typically
housed in Views or Forms).  At the same time, each of those pieces is intended
to only have a comprehension of a single Model and not the interrelationships
between said Models, resulting, for instance, in an inability to have a given
implementation accomodate more than one relation that a developer may desire
to expose to the end-user.A Solutionfoundationsets out to provide a single Backend per Django Site (website)
with Controllers specified per-model and the interrelationships between those
Controllers serving as:the Model (DB) access layer (via Model Manager and QuerySet)the View generationandaccess layer (via Class-Based Views which are, in
their own right, Controllers)the Form(Set) generation layerthe access-control layerthe URL specification layerThis design is inspired by Django’s own admin app, as well as the design
patterns of other MVC platforms.  It aims to re-use as much work from admin
out of laziness and, more importantly, a belief of mine that the admin should
be sitting atop the backend, not the all-to-often mistake new users make of
attempting to expose a front-end from within admin.How it worksIf you are not already familiar with how Django sets itself up and processes a
request, here are two links of interest:Initialization ProcessProcessing a RequestIn addition to the above, foundation does the following during initialization:foundation should be installed before all project apps to ensure the Backend
instance is in a good state prior to being referenced.  Additionally, the
app config file is a good place to instantiate your own Backend subclass if
you want to ensure any behaviors are baked into the backend used site-wide.Once applications are ready, the backend application’s ready signal will fire,
which will autodiscover all of the controllers modules/packages in each
installed app.  Additionally, permission creation for any new models will be
initiated if that feature is enabled, or you can manage that in your own app
code where appropriate (or if you implement your own permissions scheme).Finally, the URL configuration(s) are configured.  For many sites, this means
you can replace the settings ROOT_URLCONF with a path to your backend’s “urls”
attribute, although you may append it to the list of urlpatterns in the
project “urls” module to provide flexibility in adding other url specs (e.g.
admin).  When the “urls” attribute is accessed, it will perform a single pass
through all of the Controllers to accumulate the appropriate URL paths in
namespaced patterns.  At this time, all of the class-based view (CBV) base
classes will also be constructed, which will in turn be generated into
callables just-in-time (JIT) by calling their “as_view” method (same as stock
Django).Since it is operating entirely within the context of a CBV at this point, the
rest of what foundation does is essentially overriding stock Django CBV
methods, although there are some important behaviors to note that are possible
because of the controller interrelationships.  Most notably, the Django CBV
“dispatch” behavior has been universally extended by two components.A “get_handler” method is provided which allows for a given view to handle
a request using other than the CBV’s standard HTTP-method-named methods.A “handle_common” method is provided which allows for activities common to
some or all HTTP methods (e.g. auth, QS grooming) to be performed prior to
calling downstream methods to remove redundancy and clutter from those
methods.In trying to keep with some of the paradigms set forth in django-admin, this
means that for any controller- (and thus, model-) aware view, that a view “mode”
is set (e.g. add, edit, view) as well as an “edit” and “add” flag to
specifically indicate whether the view is used for editing or creation.  These
will likely move further down the stack to only be present in “html-form-aware”
views and better accommodate AJAX and RESTful views.Additionally, handle_common is where a common layer of authentication and
access-control logic occurs.  This ensures downstream views are guaranteed to
have a common logical layer invoked prior to serving a response.  By default,
the access control ships with awareness of predefined (and overridable) “public”
and “private” named views (e.g. list and view are public while add, edit, and
delete are private).  Additionally, it provides a contextual switch so that
superusers must elect to “act” as superusers, otherwise they will be subject to
the same rules as non-superusers.