Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
d7f781db
Commit
d7f781db
authored
Mar 10, 2016
by
Saleem Latif
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add SiteConfiguration configuration model to LMS
parent
1dff9d45
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
258 additions
and
1 deletions
+258
-1
cms/envs/common.py
+3
-0
lms/envs/common.py
+3
-0
openedx/core/djangoapps/site_configuration/__init__.py
+26
-0
openedx/core/djangoapps/site_configuration/migrations/0001_initial.py
+39
-0
openedx/core/djangoapps/site_configuration/migrations/__init__.py
+0
-0
openedx/core/djangoapps/site_configuration/models.py
+77
-0
openedx/core/djangoapps/site_configuration/tests/__init__.py
+0
-0
openedx/core/djangoapps/site_configuration/tests/factories.py
+16
-0
openedx/core/djangoapps/site_configuration/tests/test_models.py
+93
-0
openedx/core/djangoapps/theming/models.py
+1
-1
No files found.
cms/envs/common.py
View file @
d7f781db
...
...
@@ -823,6 +823,9 @@ INSTALLED_APPS = (
# Theming
'openedx.core.djangoapps.theming'
,
# Site configuration for theming and behavioral modification
'openedx.core.djangoapps.site_configuration'
,
# comment common
'django_comment_common'
,
...
...
lms/envs/common.py
View file @
d7f781db
...
...
@@ -1819,6 +1819,9 @@ INSTALLED_APPS = (
# Theming
'openedx.core.djangoapps.theming'
,
# Site configuration for theming and behavioral modification
'openedx.core.djangoapps.site_configuration'
,
# Our courseware
'courseware'
,
'student'
,
...
...
openedx/core/djangoapps/site_configuration/__init__.py
0 → 100644
View file @
d7f781db
"""
This app is used for creating/updating site's configuration. This app encapsulate configuration related logic for sites
and provides a way for sites to override default/system behavioural or presentation logic.
Models:
SiteConfiguration (models.Model):
This model contains configuration for a site and can be used to override OpenEdx configurations.
Fields:
site (OneToOneField): one to one field relating each configuration to a single site
values (JSONField): json field to store configurations for a site
Usage:
configuration of each site would be available as `configuration` attribute to django site.
If you want to access current site's configuration simply access it as `request.site.configuration`.
SiteConfigurationHistory (TimeStampedModel):
This model keeps a track of all the changes made to SiteConfiguration with time stamps.
Fields:
site (ForeignKey): foreign-key to django Site
values (JSONField): json field to store configurations for a site
Usage:
configuration history of each site would be available as `configuration_histories` attribute to django site.
If you want to access a list of current site's configuration history simply access it as
`request.site.configuration_histories.all()`.
"""
openedx/core/djangoapps/site_configuration/migrations/0001_initial.py
0 → 100644
View file @
d7f781db
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
import
jsonfield.fields
import
django_extensions.db.fields
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'sites'
,
'0001_initial'
),
]
operations
=
[
migrations
.
CreateModel
(
name
=
'SiteConfiguration'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
verbose_name
=
'ID'
,
serialize
=
False
,
auto_created
=
True
,
primary_key
=
True
)),
(
'values'
,
jsonfield
.
fields
.
JSONField
(
blank
=
True
)),
(
'site'
,
models
.
OneToOneField
(
related_name
=
'configuration'
,
to
=
'sites.Site'
)),
],
),
migrations
.
CreateModel
(
name
=
'SiteConfigurationHistory'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
verbose_name
=
'ID'
,
serialize
=
False
,
auto_created
=
True
,
primary_key
=
True
)),
(
'created'
,
django_extensions
.
db
.
fields
.
CreationDateTimeField
(
auto_now_add
=
True
,
verbose_name
=
'created'
)),
(
'modified'
,
django_extensions
.
db
.
fields
.
ModificationDateTimeField
(
auto_now
=
True
,
verbose_name
=
'modified'
)),
(
'values'
,
jsonfield
.
fields
.
JSONField
(
blank
=
True
)),
(
'site'
,
models
.
ForeignKey
(
related_name
=
'configuration_histories'
,
to
=
'sites.Site'
)),
],
options
=
{
'ordering'
:
(
'-modified'
,
'-created'
),
'abstract'
:
False
,
'get_latest_by'
:
'modified'
,
},
),
]
openedx/core/djangoapps/site_configuration/migrations/__init__.py
0 → 100644
View file @
d7f781db
openedx/core/djangoapps/site_configuration/models.py
0 → 100644
View file @
d7f781db
"""
Django models for site configurations.
"""
import
collections
from
django.db
import
models
from
django.contrib.sites.models
import
Site
from
django.db.models.signals
import
post_save
from
django.dispatch
import
receiver
from
django_extensions.db.models
import
TimeStampedModel
from
jsonfield.fields
import
JSONField
class
SiteConfiguration
(
models
.
Model
):
"""
Model for storing site configuration. These configuration override OpenEdx configurations and settings.
e.g. You can override site name, logo image, favicon etc. using site configuration.
Fields:
site (OneToOneField): one to one field relating each configuration to a single site
values (JSONField): json field to store configurations for a site
"""
site
=
models
.
OneToOneField
(
Site
,
related_name
=
'configuration'
)
values
=
JSONField
(
null
=
False
,
blank
=
True
,
load_kwargs
=
{
'object_pairs_hook'
:
collections
.
OrderedDict
}
)
def
__unicode__
(
self
):
return
u"<SiteConfiguration: {site} >"
.
format
(
site
=
self
.
site
)
def
__repr__
(
self
):
return
self
.
__unicode__
()
class
SiteConfigurationHistory
(
TimeStampedModel
):
"""
This is an archive table for SiteConfiguration, so that we can maintain a history of
changes. Note that the site field is not unique in this model, compared to SiteConfiguration.
Fields:
site (ForeignKey): foreign-key to django Site
values (JSONField): json field to store configurations for a site
"""
site
=
models
.
ForeignKey
(
Site
,
related_name
=
'configuration_histories'
)
values
=
JSONField
(
null
=
False
,
blank
=
True
,
load_kwargs
=
{
'object_pairs_hook'
:
collections
.
OrderedDict
}
)
def
__unicode__
(
self
):
return
u"<SiteConfigurationHistory: {site}, Last Modified: {modified} >"
.
format
(
modified
=
self
.
modified
,
site
=
self
.
site
,
)
def
__repr__
(
self
):
return
self
.
__unicode__
()
@receiver
(
post_save
,
sender
=
SiteConfiguration
)
def
update_site_configuration_history
(
sender
,
instance
,
**
kwargs
):
# pylint: disable=unused-argument
"""
Add site configuration changes to site configuration history.
Args:
sender: sender of the signal i.e. SiteConfiguration model
instance: SiteConfiguration instance associated with the current signal
**kwargs: extra key word arguments
"""
SiteConfigurationHistory
.
objects
.
create
(
site
=
instance
.
site
,
values
=
instance
.
values
,
)
openedx/core/djangoapps/site_configuration/tests/__init__.py
0 → 100644
View file @
d7f781db
openedx/core/djangoapps/site_configuration/tests/factories.py
0 → 100644
View file @
d7f781db
"""
Model factories for unit testing views or models.
"""
from
factory.django
import
DjangoModelFactory
from
openedx.core.djangoapps.site_configuration.models
import
SiteConfiguration
class
SiteConfigurationFactory
(
DjangoModelFactory
):
"""
Factory class for SiteConfiguration model
"""
class
Meta
(
object
):
model
=
SiteConfiguration
values
=
{}
openedx/core/djangoapps/site_configuration/tests/test_models.py
0 → 100644
View file @
d7f781db
"""
Tests for site configuration's django models.
"""
from
django.test
import
TestCase
from
django.db
import
IntegrityError
,
transaction
from
django.contrib.sites.models
import
Site
from
openedx.core.djangoapps.site_configuration.models
import
SiteConfigurationHistory
from
openedx.core.djangoapps.site_configuration.tests.factories
import
SiteConfigurationFactory
class
SiteConfigurationTests
(
TestCase
):
"""
Tests for SiteConfiguration and its signals/receivers.
"""
domain
=
'site_configuration_post_save_receiver_example.com'
name
=
'site_configuration_post_save_receiver_example'
@classmethod
def
setUpClass
(
cls
):
super
(
SiteConfigurationTests
,
cls
)
.
setUpClass
()
cls
.
site
,
_
=
Site
.
objects
.
get_or_create
(
domain
=
cls
.
domain
,
name
=
cls
.
domain
)
def
test_site_configuration_post_save_receiver
(
self
):
"""
Test that and entry is added to SiteConfigurationHistory model each time a new
SiteConfiguration is added.
"""
# add SiteConfiguration to database
site_configuration
=
SiteConfigurationFactory
.
create
(
site
=
self
.
site
,
)
# Verify an entry to SiteConfigurationHistory was added.
site_configuration_history
=
SiteConfigurationHistory
.
objects
.
filter
(
site
=
site_configuration
.
site
,
)
.
all
()
# Make sure an entry (and only one entry) is saved for SiteConfiguration
self
.
assertEqual
(
len
(
site_configuration_history
),
1
)
def
test_site_configuration_post_update_receiver
(
self
):
"""
Test that and entry is added to SiteConfigurationHistory each time a
SiteConfiguration is updated.
"""
# add SiteConfiguration to database
site_configuration
=
SiteConfigurationFactory
.
create
(
site
=
self
.
site
,
)
site_configuration
.
values
=
{
'test'
:
'test'
}
site_configuration
.
save
()
# Verify an entry to SiteConfigurationHistory was added.
site_configuration_history
=
SiteConfigurationHistory
.
objects
.
filter
(
site
=
site_configuration
.
site
,
)
.
all
()
# Make sure two entries (one for save and one for update) are saved for SiteConfiguration
self
.
assertEqual
(
len
(
site_configuration_history
),
2
)
def
test_no_entry_is_saved_for_errors
(
self
):
"""
Test that and entry is not added to SiteConfigurationHistory if there is an error while
saving SiteConfiguration.
"""
# add SiteConfiguration to database
site_configuration
=
SiteConfigurationFactory
.
create
(
site
=
self
.
site
,
)
# Verify an entry to SiteConfigurationHistory was added.
site_configuration_history
=
SiteConfigurationHistory
.
objects
.
filter
(
site
=
site_configuration
.
site
,
)
.
all
()
# Make sure entry is saved if there is no error
self
.
assertEqual
(
len
(
site_configuration_history
),
1
)
with
transaction
.
atomic
():
with
self
.
assertRaises
(
IntegrityError
):
# try to add a duplicate entry
site_configuration
=
SiteConfigurationFactory
.
create
(
site
=
self
.
site
,
)
site_configuration_history
=
SiteConfigurationHistory
.
objects
.
filter
(
site
=
site_configuration
.
site
,
)
.
all
()
# Make sure no entry is saved if there an error
self
.
assertEqual
(
len
(
site_configuration_history
),
1
)
openedx/core/djangoapps/theming/models.py
View file @
d7f781db
"""
Comprehensive Theme related models.
Django models supporting the Comprehensive Theming subsystem
"""
from
django.db
import
models
from
django.contrib.sites.models
import
Site
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment