Commits

Hynek Cernoch committed a00be86

Added test, added standalone example, settings compatible with Django 1.3 + 1.2, fixed ModuleValue, documentation fixed, small fixes, removed relicts

Comments (0)

Files changed (10)

 Usage
 =====
 
+Very simple example project is in directory livesettings/test_app, almost identical with the following description.
+
 Creating Config.py
 ------------------
 
 
     python manage.py runserver
     
-Restricting Access to Livesettings
-----------------------------------
-
-In order to give non-superusers access to the settings, make sure to use the django user permission admin screen to give the desired user the *livesettings|setting|Can change settting*.
-
-.. Note::
-    Superusers will have access to this setting without enabling any specific permissions
-
-Permissions for insert, delete or permission for longsetting are ignored and only the above-mentioned permission is used.
-
-Exporting Settings
-------------------
-
-Settings can be exported by the `http://127.0.0.1:8000/settings/export/ <http://127.0.0.1:8000/settings/export/>`_ . After exporting the file, the entire
-output can be manually copied and pasted to :file:`settings.py`. If you restrict DB access to the settings, all of the livesettings_* tables
-will be unused. 
-
-Here is a simple example of what the extract will look like::
-
-    LIVESETTINGS_OPTIONS = \
-    {   1: {   'DB': False,
-               'SETTINGS': {   u'MyApp': {   u'DECIMAL_TEST': u'34.0923443',
-                                             u'MEASUREMENT_SYSTEM': u'["metric"]',
-                                             u'PERCENT_TEST': u'0.251'}}}}
-
-In order to restrict or enable DB access, use the following line in your settings::
-
-    'DB': True,    # or False
-
-If you have multiple sites, they can be manually combined in the file as well.
-
 Accessing your value in a view
 ------------------------------
 
     <p>You want to show {{image_count}} pictures and use the {{measurement_system}} system.</p>
 
 
+Restricting Access to Livesettings
+----------------------------------
+
+In order to give non-superusers access to the settings, make sure to use the django user permission admin screen to give the desired user the *livesettings|setting|Can change settting*.
+
+.. Note::
+    Superusers will have access to this setting without enabling any specific permissions
+
+Permissions for insert, delete or permission for longsetting are ignored and only the above-mentioned permission is used.
+
+Exporting Settings
+------------------
+
+Settings can be exported by the `http://127.0.0.1:8000/settings/export/ <http://127.0.0.1:8000/settings/export/>`_ . After exporting the file, the entire
+output can be manually copied and pasted to :file:`settings.py` in order to deploy configuration to more sites or to entirely prevent further changes.
+If you restrict DB access to the settings, all of the livesettings_* tables will be unused. 
+
+Here is a simple example of what the extract will look like::
+
+    LIVESETTINGS_OPTIONS = \
+    {   1: {   'DB': False,
+               'SETTINGS': {   u'MyApp': {   u'DECIMAL_TEST': u'34.0923443',
+                                             u'MEASUREMENT_SYSTEM': u'["metric"]',
+                                             u'PERCENT_TEST': u'0.251'}}}}
+
+In order to restrict or enable DB access, use the following line in your settings::
+
+    'DB': True,    # or False
+
+If you have multiple sites, they can be manually combined in the file as well.
+
 Next Steps
 ----------
 

livesettings/test_app/localsite/config.py

+from livesettings import config_register, ConfigurationGroup, PositiveIntegerValue, MultipleStringValue, ModuleValue
+from django.utils.translation import ugettext_lazy as _
+
+# First, setup a grup to hold all our possible configs
+MYAPP_GROUP = ConfigurationGroup('MyApp', _('My App Settings'), ordering=0)
+
+# Now, add our number of images to display value
+# If a user doesn't enter a value, default to 5
+config_register(PositiveIntegerValue(
+    MYAPP_GROUP,
+        'NUM_IMAGES',
+        description = _('Number of images to display'),
+        help_text = _("How many images to display on front page."),
+        default = 5
+    ))
+
+# Another example of allowing the user to select from several values
+config_register(MultipleStringValue(
+        MYAPP_GROUP,
+        'MEASUREMENT_SYSTEM',
+        description=_("Measurement System"),
+        help_text=_("Default measurement system to use."),
+        choices=[('metric',_('Metric')),
+                    ('imperial',_('Imperial'))],
+        default="imperial"
+    ))
+
+config_register(ModuleValue(
+        MYAPP_GROUP,
+        'MODULE',
+        #description=_("Measurement System"),
+        #help_text=_("Default measurement system to use."),
+        default="django"
+    ))

livesettings/test_app/localsite/models.py

+import config

livesettings/test_app/localsite/templates/myapp/index.html

+<html><body>
+<pre>
+<p>Measurement system: {{ measurement_system }}</p>
+<p>Image count: {{ image_count }}</p>
+<p><a href="{% url satchmo_site_settings %}">Values can be modified</a> if the user has sufficient permissions (livesettings_setting:change).</p>
+</body></html>

livesettings/test_app/localsite/views.py

+from django.shortcuts import render_to_response
+from livesettings import config_value
+
+def index(request):
+    image_count = config_value('MyApp','NUM_IMAGES')
+    # Note, the measurement_system will return a list of selected values
+    # in this case, we use the first one
+    measurement_system = config_value('MyApp','MEASUREMENT_SYSTEM')
+    return render_to_response('myapp/index.html',
+                            {'image_count': image_count,
+                            'measurement_system': measurement_system[0]})

livesettings/test_app/manage.py

 import sys
 
 DIRNAME = os.path.dirname(__file__)
-# trick to get the two-levels up directory, which for the "simple" project should be the satchmo dir
-_parent = lambda x: os.path.normpath(os.path.join(x, '..'))
-
-SATCHMO_DIRNAME = _parent(_parent(DIRNAME))
-SATCHMO_APPS = os.path.join(SATCHMO_DIRNAME, 'apps')
-
-if not SATCHMO_APPS in sys.path:
-    sys.path.append(SATCHMO_APPS)
 
 if not DIRNAME in sys.path:
     sys.path.append(DIRNAME)

livesettings/test_app/settings.py

-# Django settings for satchmo project.
+# Django settings.
 # If you have an existing project, then ensure that you modify local_settings-customize.py
 # and import it from your main settings file. (from local_settings import *)
 import os
 
 DIRNAME = os.path.dirname(__file__)
 
-DJANGO_PROJECT = 'tests'
-DJANGO_SETTINGS_MODULE = 'tests.settings'
+DJANGO_PROJECT = 'test_app'
+DJANGO_SETTINGS_MODULE = 'test_app.settings'
 
 ADMINS = (
      ('', ''),
 
 MANAGERS = ADMINS
 
-DATABASE_ENGINE = 'sqlite3'           # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
-DATABASE_NAME = 'test.db'             # Or path to database file if using sqlite3.
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3',  # 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'ado_mssql'.
+        'NAME': 'test.db',
+    }
+}
 
 # Local time zone for this installation. All choices can be found here:
 # http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
 
 # List of callables that know how to import templates from various sources.
 TEMPLATE_LOADERS = (
-    'django.template.loaders.filesystem.load_template_source',
-    'django.template.loaders.app_directories.load_template_source',
+    'django.template.loaders.filesystem.Loader',
+    'django.template.loaders.app_directories.Loader',
 #     'django.template.loaders.eggs.load_template_source',
 )
 
     "django.contrib.sessions.middleware.SessionMiddleware",
     "django.middleware.locale.LocaleMiddleware",
     "django.contrib.auth.middleware.AuthenticationMiddleware",
+    "django.contrib.messages.middleware.MessageMiddleware",
     "django.middleware.doc.XViewMiddleware",
     #'debug_toolbar.middleware.DebugToolbarMiddleware',
 )
 
-#this is used to add additional config variables to each request
-# NOTE: overridden in local_settings.py
-# NOTE: If you enable the recent_products context_processor, you MUST have the
-# 'satchmo_ext.recentlist' app installed.
-TEMPLATE_CONTEXT_PROCESSORS = ('django.core.context_processors.auth',)
+TEMPLATE_CONTEXT_PROCESSORS = ('django.contrib.auth.context_processors.auth',)
 
-ROOT_URLCONF = 'tests.urls'
+ROOT_URLCONF = 'test_app.urls'
 
 INSTALLED_APPS = (
     'django.contrib.sites',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.comments',
+    'django.contrib.flatpages',
     'django.contrib.sessions',
     'django.contrib.sitemaps',
     'livesettings',
     'keyedcache',
-    'tests.localsite',
+    'test_app.localsite',
 )
 
 AUTHENTICATION_BACKENDS = (
 
 CACHE_PREFIX = 'T'
 CACHE_TIMEOUT = 300
+DEBUG = True

livesettings/test_app/urls.py

 admin.autodiscover()
 
 urlpatterns = patterns('',
-    (r'^admin/settings/$', include('livesettings.urls')),
+    (r'^settings/', include('livesettings.urls')),
+    (r'^admin/', include(admin.site.urls)),
+    (r'^accounts/login/', 'django.contrib.auth.views.login', {'template_name': 'admin/login.html'}),
+    (r'^$', 'localsite.views.index')
 )

livesettings/tests.py

 from django.conf import settings as djangosettings
+from django.core.urlresolvers import reverse
 from django.test import TestCase
 import keyedcache
 from livesettings import *
         self.g = g
         self.c = config_register(ModuleValue(g, 'test'))
 
-    # def testModule(self):
-    #     c = config_get('modules', 'test')
-    #     c.update('satchmo_store')
+    def testModule(self):
+        c = config_get('modules', 'test')
+        c.update('django')
 
-    #     self.assert_(hasattr(self.c.value, 'get_version'))
+        self.assert_(hasattr(self.c.value, 'get_version'))
 
 class ConfigTestSortOrder(TestCase):
     def setUp(self):
         self.assertEqual(v[0], "one")
         self.assertEqual(v[1], "two")
         self.assertEqual(v[2], "three")
+
+
+class PermissionTest(TestCase):
+    """Test access permissions"""
+    def setUp(self):
+        from django.contrib.auth.models import Permission, User
+        from django.contrib.contenttypes.models import ContentType
+
+        opts = Setting._meta
+        user1 = User.objects.create_user('warehouseman', 'john@example.com', 'secret')
+        user1.is_staff = True
+        user1.save()
+        user2 = User.objects.create_user('developer', 'fred@example.com', 'secret')
+        user2.is_staff = True
+        user2.user_permissions.add(Permission.objects.get(codename='change_setting', 
+                content_type=ContentType.objects.get(app_label='livesettings', model='setting'), codename='change_setting'))
+        user2.save()
+
+        keyedcache.cache_delete()
+        value = IntegerValue(BASE_GROUP, 'SingleItem')
+        config_register(value)
+
+    def testUnauthorized(self):
+        """Unauthorized or staff without enought additional permission"""
+        response = self.client.get('/settings/')
+        self.assertRedirects(response, '/accounts/login/?next=' + reverse('satchmo_site_settings'))
+        self.assertEqual(response.status_code, 302)
+        self.client.login(username='warehouseman', password='secret')
+        response = self.client.get('/settings/')
+        #self.assertRedirects(response.status_code)
+        self.assertEqual(response.status_code, 302)
+
+    def testAuthorizedEnough(self):
+        self.client.login(username='developer', password='secret')
+        response = self.client.get('/settings/')
+        self.assertContains(response, 'SingleItem')

livesettings/values.py

         if value == NOTSET:
             v = {}
         else:
-            v = load_module(value)
+            try:
+                v = load_module(value)
+            except ImportError:
+                v = ''
         return v
 
+    def get_db_prep_save(self, value):
+        return value.__name__
+
     def to_editor(self, value):
         if value == NOTSET:
             value = ""