Before the fix in e97ec27c95, the new
get_classes threw an AppNotFoundError whereas get_classes prior to the
refactor did not.
The condition is that neither the local module nor the Oscar module
could be imported. Our reasoning is that this is an issue with circular
imports. Before the refactor of get_classes, not being able to import
the Oscar in the shortcut path (beginning of function) would raise an
ImportError; which is then masked by a wrapping get_classes call. Hence,
the circular import is hidden.
This fix highlights the condition explicitly by raising an error that is
intentionally not an ImportError.
Investigation following a mailing list thread
(https://groups.google.com/d/msgid/django-oscar/a1489359-cfa6-44dc-90d8-2958be9e88a1%40googlegroups.com)
highlighted that an overriding app can't be a root app, e.g. overriding
'oscar.dashboard' with an app called 'dashboard' did not work.
In the past, there's been a lot of subtle issues surrounding the
get_classes code. Hence, some effort was expended to make the logic more
readable and fix the issue. Docstrings have been expanded, comments have
been written and private methods have been renamed.
Fix for get_classes when used with non-Oscar modules
get_classes allows imported_oscar_module to be None.
imported_oscar_module ends up in modules in _pluck_classes, however the
code is not prepared to handle None at that place.
Fixes #1160.
Thanks to @mberthau for reporting and supplying fix.
Django's get_model returns None if the import fails, which causes subtle
bugs further down the line. This change introduces a wrapper around it
which raises an ImportError instead, hence catching the error as early
as possible.
The code assumed that an application instance and it's views have the
same parent module. This is not necessarily true, as one can customise
either just a view or just an app.
The fix consists of always using get_class to load the application
instance.
@mberthau pointed out the issue and provided a first fix in #993 and #1034.
Introduces the concept of a "feature" that can be hidden. A list of
features to hide can be supplied in OSCAR_HIDDEN_FEATURES.
Feature hiding is currently supported in two places.
Application instances can carry a "hidable_feature_name". If set and
found in OSCAR_HIDDEN_FEATURES, post_process_urls will return an empty
set of url patterns, hence disabling relevant views.
display_tags also has a new template block tag iffeature.
{% iffeature "feature" %}xxx{% endiffeature %} will hide everything
inside the block if the feature is hidden.