idlesign / django-siteprefs

Reusable app for Django introducing site preferences system
https://github.com/idlesign/django-siteprefs
BSD 3-Clause "New" or "Revised" License
17 stars 6 forks source link

Incorrect app-variable when using an unconventional project structure #10

Closed kristofelst closed 8 years ago

kristofelst commented 9 years ago

Following the quick start tutorial of the docs, I came across an error I can't fix at this moment. It is a KeyError for the value apps.settings. I think it has something to do with my rather unconventional project structure:

root-of-django-project
|--apps
   |--base
      urls.py
   |--product_management
      |--search
         settings.py
|--settings
   common.py

Here, only search and base are Django apps, the rest are just Python Packages. I have put autodiscover_siteprefs() in urls.py of base, and put a preference declaration as described in the tutorial in the settings.py of search:


from siteprefs.toolbox import patch_locals, register_prefs, pref, pref_group

NEW_TIMESPAN_DAYS = 5

patch_locals()

register_prefs(
    pref_group('Filter settings', (NEW_TIMESPAN_DAYS,), static=False),
    pref(NEW_TIMESPAN_DAYS, verbose_name='Tijdspanne voor "new" filter',
         static=False, help_text="""Het aantal dagen dat het uploaden van het product geleden mag zijn,
         om een product nog steeds te bestempelen als nieuw"""),
)

When running the server I get a KeyError for 'apps.settings'. It has the following traceback:


File "/Volumes/Dataschijf/Software_Dev/Cazou/cazou-web/env/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  98.                 resolver_match = resolver.resolve(request.path_info)
File "/Volumes/Dataschijf/Software_Dev/Cazou/cazou-web/env/lib/python2.7/site-packages/django/core/urlresolvers.py" in resolve
  343.             for pattern in self.url_patterns:
File "/Volumes/Dataschijf/Software_Dev/Cazou/cazou-web/env/lib/python2.7/site-packages/django/core/urlresolvers.py" in url_patterns
  372.         patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/Volumes/Dataschijf/Software_Dev/Cazou/cazou-web/env/lib/python2.7/site-packages/django/core/urlresolvers.py" in urlconf_module
  366.             self._urlconf_module = import_module(self.urlconf_name)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py" in import_module
  37.     __import__(name)
File "/Volumes/Dataschijf/Software_Dev/Cazou/cazou-web/cazou/apps/base/urls.py" in 
  22. autodiscover_siteprefs()
File "/Volumes/Dataschijf/Software_Dev/Cazou/cazou-web/env/lib/python2.7/site-packages/siteprefs/toolbox.py" in autodiscover_siteprefs
  99.         register_admin_models()
File "/Volumes/Dataschijf/Software_Dev/Cazou/cazou-web/env/lib/python2.7/site-packages/siteprefs/toolbox.py" in register_admin_models
  84.         model_class = get_pref_model_class(app_label, prefs_items, get_app_prefs)
File "/Volumes/Dataschijf/Software_Dev/Cazou/cazou-web/env/lib/python2.7/site-packages/siteprefs/utils.py" in get_pref_model_class
  134.         model = type('Preferences', (models.Model,), model_dict)
File "/Volumes/Dataschijf/Software_Dev/Cazou/cazou-web/env/lib/python2.7/site-packages/django/db/models/base.py" in __new__
  107.                 model_module = sys.modules[new_class.__module__]

When looking at the local variables in the get_pref_model_class method, I see that for the preference I declared, the variable app is 'apps' instead of 'search':

prefs_items: OrderedDict([('new_timespan_days', NEW_TIMESPAN_DAYS = 5)])
prefs: OrderedDict([('apps', OrderedDict([('new_timespan_days', NEW_TIMESPAN_DAYS = 5)]))])
app_label: 'apps'

So my guess is that it is taking the root map of all the apps as django-app, and not the correct app (search). Since the Python Package apps has no file called settings, it crashes.

So my question is, does siteprefs makes some assumptions about the file structure of the project or did I make some mistake? How can I make it work for my file structure?

Thanks in advance!

idlesign commented 9 years ago

Hi,

Indeed siteprefs relies on project structure and should support classic pre and post 1.4 layouts - https://github.com/idlesign/django-siteprefs/blob/master/siteprefs/utils.py#L225

In a week I'll think over what we might want to do in cases similar to yours, maybe some kind of heuristics or even explicit setup. If you have any ideas you're welcome.

kristofelst commented 9 years ago

Since this project looks the best, and the most natural way of dealing with live settings, it would be really nice if it could deal with rather unconventional project structures.

Can't you just look at the packages which contain a settings.py file, and label them as being the django-app for that settings file?

idlesign commented 9 years ago

Unfortunately things are more complex than that. Here is a probable culprit: https://github.com/idlesign/django-siteprefs/blob/master/siteprefs/toolbox.py#L49

To solve the issue we might have introduce some module attribute holding a proper app name that one could define in settings.py of apps, before trying name attribute. Or there may be some other more appropriate way. That requires further investigation.

That'll be nice if you provide a stub of your project with more stuff that described above: with manage.py, several apps, etc. (real stuff not required)

idlesign commented 8 years ago

Simple KeyError workaround is in 0.6.0. That should do for most cases. Closing this one. Feel fre to reopen if required.