Django CMS QE¶
Django CMS Quick & Easy provides all important modules to run new page without a lot of coding. Aims to do it very easily and securely.
API¶
Settings¶
Settings is stored in cms_qe.settings
. You can find few prepared ready-to-use environments:
- prod,
- dev
- and test.
First one is for production use. It means at your app you should just import everything from there and add what you have to change (your paths and database for example). Actually the minimum config is for example this one:
import os
from cms_qe.settings.prod import *
INSTALLED_APPS += [
'example',
]
ROOT_URLCONF = 'example.urls'
WSGI_APPLICATION = 'example.wsgi.application'
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
Security¶
Big goal is to have this library secure, so it has by default those main settings ready:
- Used HTTPS with HSTS with all subdomains (but no preload).
- Session cookie is secure and readable by HTTP only.
- Page can be used in iframe only on the same domain (turn on only because of Django CMS).
- CSP header to not allow any not trusted content.
- XSS-protection header to not allow run any script submitted by form.
- Content-type: nosniff header to not allow run any page or script uploaded as a file.
- Use CSRF to not allow make dangerous post request outside of the page.
- Save password very securely by latest best algorithm.
- Use password validators to allow at least 8 characters which should not be user name, common password or all numeric.
- Use
django-axes
to limit authorization (after 5 attempts is username and IP banned for one hour, can be changed by custom configuration).
Tip: when you want to just test page without final configuration, it’s good to temporally disable CSP header in your config (actually - just report but don’t block):
CSP_REPORT_ONLY = True
If your test environment do not run with SSL, then you should turn it off:
META_SITE_PROTOCOL = 'http'
SESSION_COOKIE_SECURE = False
SECURE_HSTS_SECONDS = 0
If your website is behind proxy, you have to set Django AXES to properly limit brute-force authorization by one of those options (more about that in documentation:
AXES_REVERSE_PROXY_HEADER = 'header'
AXES_NUM_PROXIES = 1
Views¶
-
cms_qe.views.errors.
handler500
(request: django.http.request.HttpRequest) → django.http.response.HttpResponseBase[source]¶ When application fail on internal error, Django CMS has problem to render any page. They don’t have any API for rendering any page so it’s impossible to get it right. Solution could be just redirect to page with given slug but it could also hang in infinite loop of redirection if there would be problem on page with slug error500.
That’s why we simply just use different template which cannot be changed in admin by user. To override default template, just create your own
cms_qe/internal_error.html
or changehandler500
to your own view.
-
cms_qe.views.errors.
get_error_handler
(code: int) → Callable[[django.http.request.HttpRequest], django.http.response.HttpResponseBase][source]¶ Decorator creating error handler for specific HTTP status code.
When CMS page with slug
errorCODE
exists, then is shown that page, otherwise generic one. Page is not cached because of that.Possible slugs:
- error403 (forbidden)
- error404 (not found)
- error503 (service unavailable)
-
cms_qe.views.monitoring.
get_monitoring
(request)[source]¶ Returns JSON response with data about monitoring of application.
-
cms_qe.views.monitoring.
get_monitoring_data
()[source]¶ Helper to check all installed apps. It looks for function
get_status
in modulesmonitoring
. If you want to add check for your module, create your file calledmonitoring.py
and add something like this:def get_status(): # check return True # or False or error message or dict
Result is dictionary of two keys, overall
status
which isTrue
is all calls returnsTrue
, in other casesFalse
. Second key isapp_details
with dictionary with key of every app which has monitoring and it’s status. Status can be bool or any message which means something is wrong.You can also return dictionary with the details of your app. For example:
{ 'databse': True, 'cache': 'problem to connect', # ... }
-
cms_qe.views.security.
csp_report
(request: django.http.request.HttpRequest) → django.http.response.HttpResponse[source]¶ View handling reports by CSP headers. When there is problem by CSP, then browser fire request to this view with JSON data describing problem. It’s simply just logged as warning for later analyzing.
Template tags and filters¶
Same as
django.template.defaultfilters.add()
but always convert tostr
.
Get sequence item at the position.
The value matches pattern.
Split the value by the delimiter.
Other¶
-
class
cms_qe.export.
AdminField
(*args, **kwds)[source]¶ Field to support including extra fields defined in the variable ModelAdmin.list_display. Original fields.Field is capable to get property so we need to only add support of extra fields defined on the ModelAdmin itself.
-
class
cms_qe.export.
ChoicesWidget
(choices, *args, **kwargs)[source]¶ Widget that uses choice display values in place of database values
-
class
cms_qe.export.
ExportType
(mimetype, label)¶ -
label
¶ Alias for field number 1
-
mimetype
¶ Alias for field number 0
-
-
cms_qe.export.
export_data
(export_type, modeladmin, queryset)[source]¶ Export data as
export_type
. Supported are only those from functionget_supported_export_types
.
-
cms_qe.export.
export_file
(export_type, modeladmin, queryset)[source]¶ Same as
cms_qe.export.export_data
but wraps it intodjango.http.HttpResponse
as file to download.
-
cms_qe.export.
get_supported_export_types
()[source]¶ Get only the export types supported by this operating system.
-
cms_qe.export.
register_export_action
(export_type, label)[source]¶ Helper to register export action to specific type. It dynamically creates action function and register it as
admin.site.add_action
with passed label.
-
class
cms_qe.staticfiles.
ManifestStaticFilesStorage
(*args, manifest_storage=None, **kwargs)[source]¶ Custom handle of
django.contrib.staticfiles.storage.ManifestStaticFilesStorage
to create different URLs for every version of static file. Means when you change static file, Django’scollectstatic
detects that and createsstaticfiles.json
with all hashes and adds them to URLs when tagstatic
is used.It’s good to use this when you don’t want to have problems with caches–when you change static but cache still serves the old one with new generated HTML. Thanks to this storage you can be sure that every client will use new resources needed by new page.
This custom version takes care of compatiblity of Django CMS which brings custom static tag to add owns version and then Django’s storage has problem to cooperate with it. In Django 1.10 it has to override
stored_name
to ignore this problem and in Django 1.11 is brought new attributemanifest_strict
which has to be set toFalse
to work as in Django 1.10.
-
cms_qe.utils.
get_base_url
(request) → str[source]¶ Helper to get absolute URL of application. It requires to set correctly domain of site framework.
-
cms_qe.utils.
get_email
(template: str, subject: str, to: Union[str, collections.abc.Iterable[str]], from_email: Optional[str, None] = None, **kwargs)[source]¶ Returns a
MailerMessage
instance frommailqueue
. Usesave()
method instead ofsend()
to send message or put it to a mailqueue.Template should be without extension and you should create both
.txt
and.html
version. Second one is not mandatory but is good to provide it as well.
-
cms_qe.utils.
get_functions
(module_name: str, function_name: str) → collections.abc.Iterable[tuple][source]¶ Get function by
function_name
ofmodule_name
for every installed Django app. Returns tuple ofapp_name
andfunction
. Example usage:for app, func in get_functions('monitoring', 'get_status'): # ...