diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index e1d97aed..5cd2b3d1 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -15,6 +15,22 @@ are used for versioning (schema follows below):
0.3.4 to 0.4).
- All backwards incompatible changes are mentioned in this document.
+0.10.8
+------
+yyyy-mm-dd (not yet released)
+
+- Documentation fixes.
+- PEP8 code fixes.
+- Minor setup fixes related to moved screen-shots file.
+- Added helper scripts to test with Firefox in headless mode. Describe
+ testing with Firefox in headless mode in documentation.
+
+0.10.7
+------
+2017-03-13
+
+- Several Django deprecation/moves fixes for better future compatibility.
+
0.10.6
------
2017-02-14
diff --git a/QUICK_START.rst b/QUICK_START.rst
index 4084fb25..554797bc 100644
--- a/QUICK_START.rst
+++ b/QUICK_START.rst
@@ -16,14 +16,14 @@ Installation and configuration
------------------------------
Install the package in your environment.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. code-block:: none
+.. code-block:: sh
pip install django-fobi
INSTALLED_APPS
^^^^^^^^^^^^^^
Add ``fobi`` core and the plugins to the ``INSTALLED_APPS`` of the your
-`settings` module.
+``settings`` module.
1. The core.
@@ -47,7 +47,7 @@ Add ``fobi`` core and the plugins to the ``INSTALLED_APPS`` of the your
`_
would require additional packages to be installed. If so, make sure to have
installed and configured those dependencies prior adding the dependant
- add-ons to the `settings` module.
+ add-ons to the ``settings`` module.
.. code-block:: python
@@ -82,7 +82,7 @@ Add ``fobi`` core and the plugins to the ``INSTALLED_APPS`` of the your
.. code-block:: python
- 'easy_thumbnails', # Required by `content_image` plugin
+ 'easy_thumbnails', # Required by `content_image` plugin
'fobi.contrib.plugins.form_elements.content.content_image',
'fobi.contrib.plugins.form_elements.content.content_text',
'fobi.contrib.plugins.form_elements.content.content_video',
@@ -145,7 +145,7 @@ Putting all together, you would have something like this.
'fobi.contrib.plugins.form_elements.fields.url',
# Form element plugins
- 'easy_thumbnails', # Required by `content_image` plugin
+ 'easy_thumbnails', # Required by ``content_image`` plugin
'fobi.contrib.plugins.form_elements.content.content_image',
'fobi.contrib.plugins.form_elements.content.content_text',
'fobi.contrib.plugins.form_elements.content.content_video',
@@ -162,21 +162,21 @@ TEMPLATE_CONTEXT_PROCESSORS
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Add ``django.core.context_processors.request`` and
``fobi.context_processors.theme`` to ``TEMPLATE_CONTEXT_PROCESSORS`` of
-your `settings` module.
+your ``settings`` module.
.. code-block:: python
TEMPLATE_CONTEXT_PROCESSORS = (
# ...
"django.core.context_processors.request",
- "fobi.context_processors.theme", # Obligatory
- "fobi.context_processors.dynamic_values", # Optional
+ "fobi.context_processors.theme", # Obligatory
+ "fobi.context_processors.dynamic_values", # Optional
# ...
)
urlpatterns
^^^^^^^^^^^
-Add the following line to ``urlpatterns`` of your `urls` module.
+Add the following line to ``urlpatterns`` of your ``urls`` module.
.. code-block:: python
@@ -201,21 +201,21 @@ Update the database
1. First you should be syncing/migrating the database. Depending on your
Django version and migration app, this step may vary. Typically as follows:
-.. code-block:: none
+.. code-block:: sh
- $ ./manage.py syncdb
- $ ./manage.py migrate --fake-initial
+ ./manage.py syncdb
+ ./manage.py migrate --fake-initial
2. Sync installed ``fobi`` plugins. Go to terminal and type the following
command.
-.. code-block:: none
+.. code-block:: sh
- $ ./manage.py fobi_sync_plugins
+ ./manage.py fobi_sync_plugins
Specify the active theme
^^^^^^^^^^^^^^^^^^^^^^^^
-Specify the default theme in your `settings` module.
+Specify the default theme in your ``settings`` module.
.. code-block:: python
diff --git a/README.rst b/README.rst
index 5f3f0b38..6e55e84f 100644
--- a/README.rst
+++ b/README.rst
@@ -302,8 +302,9 @@ Add the following line to urlpatterns of your `urls` module.
url(r'^fobi/', include('fobi.urls.edit')),
Note, that some plugins require additional URL includes. For instance, if you
-listed the `fobi.contrib.plugins.form_handlers.db_store` form handler plugin
-in the ``INSTALLED_APPS``, you should mention the following in `urls` module.
+listed the ``fobi.contrib.plugins.form_handlers.db_store`` form handler plugin
+in the ``INSTALLED_APPS``, you should mention the following in ``urls``
+module.
.. code-block:: python
@@ -344,8 +345,8 @@ There are several properties, each textarea should have. They are:
- `required` (bool): Flag, which tells us whether the field is required or
optional.
-Let's name that plugin `sample_textarea`. The plugin directory should then have
-the following structure.
+Let's name that plugin ``sample_textarea``. The plugin directory should then
+have the following structure.
.. code-block:: sh
@@ -368,7 +369,7 @@ Define and register the form element plugin
-------------------------------------------
Step by step review of a how to create and register a plugin and plugin
widgets. Note, that `django-fobi` auto-discovers your plugins if you place
-them into a file named `fobi_form_elements.py` of any Django app listed in
+them into a file named ``fobi_form_elements.py`` of any Django app listed in
``INSTALLED_APPS`` of your Django projects' settings module.
path/to/sample_textarea/fobi_form_elements.py
@@ -475,11 +476,11 @@ path/to/sample_textarea/forms.py
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Why to have another file for defining forms? Just to keep the code clean and
less messy, although you could perfectly define all your plugin forms in the
-module `fobi_form_elements.py`, it's recommended to keep it separate.
+module ``fobi_form_elements.py``, it's recommended to keep it separate.
-Take into consideration, that `forms.py` is not an auto-discovered file pattern.
-All your form element plugins should be registered in modules named
-`fobi_form_elements.py`.
+Take into consideration, that ``forms.py`` is not an auto-discovered file
+pattern. All your form element plugins should be registered in modules named
+``fobi_form_elements.py``.
Required imports.
@@ -631,7 +632,7 @@ Do check the source code as example.
Define and register the form handler plugin
-------------------------------------------
-Let's name that plugin `sample_mail`. The plugin directory should then have
+Let's name that plugin ``sample_mail``. The plugin directory should then have
the following structure.
.. code-block:: text
@@ -704,11 +705,11 @@ plugin is configurable, it should have a form.
Why to have another file for defining forms? Just to keep the code clean and
less messy, although you could perfectly define all your plugin forms in the
-module `fobi_form_handlers.py`, it's recommended to keep it separate.
+module ``fobi_form_handlers.py``, it's recommended to keep it separate.
-Take into consideration, that `forms.py` is not an auto-discovered file pattern.
-All your form handler plugins should be registered in modules named
-`fobi_form_handlers.py`.
+Take into consideration, that ``forms.py`` is not an auto-discovered file
+pattern. All your form handler plugins should be registered in modules named
+``fobi_form_handlers.py``.
Required imports.
@@ -837,8 +838,8 @@ existing MailChimp forms into `django-fobi`.
Define and register the form importer plugin
--------------------------------------------
-Let's name that plugin `sample_importer`. The plugin directory should then have
-the following structure.
+Let's name that plugin ``sample_importer``. The plugin directory should then
+have the following structure.
.. code-block:: text
@@ -938,7 +939,7 @@ Required imports.
from django import forms
from django.utils.translation import ugettext_lazy as _
- from sample_service_api import sample_api # Just an imaginary API client
+ from sample_service_api import sample_api # Just an imaginary API client
Defining the form for Sample importer plugin.
@@ -988,7 +989,8 @@ Required imports.
from formtools.wizard.views import SessionWizardView
from path.to.sample_importer.forms import (
- SampleImporterStep1Form, SampleImporterStep2Form
+ SampleImporterStep1Form,
+ SampleImporterStep2Form,
)
Defining the wizard view for Sample importer plugin.
@@ -1076,9 +1078,8 @@ Creating a form callback
Form callbacks are additional hooks, that are executed on various stages of
the form submission.
-Let's place the callback in the `foo` module. The plugin directory should then
-have the following
-structure.
+Let's place the callback in the ``foo`` module. The plugin directory should
+then have the following structure.
.. code-block:: text
@@ -1162,7 +1163,7 @@ themes:
- "Foundation 5" theme
- "Simple" theme in (with editing interface in style of the Django admin)
- "DjangoCMS admin style" theme (which is another simple theme with editing
- interface in style of `djangocms-admin-style`)
+ interface in style of ``djangocms-admin-style``)
Obviously, there are two sorts of views when it comes to editing and viewing
the form.
@@ -1192,7 +1193,7 @@ the "Simple" theme is the best start, since it looks just like django-admin.
Create a new theme
------------------
-Let's place the theme in the `sample_theme` module. The theme directory
+Let's place the theme in the ``sample_theme`` module. The theme directory
should then have the following structure.
.. code-block:: text
@@ -1292,7 +1293,7 @@ Registering the ``SampleTheme`` plugin.
Sometimes you would want to attach additional properties to the theme
in order to use them later in templates (remember, current theme object
-is always available in templates under name `fobi_theme`).
+is always available in templates under name ``fobi_theme``).
For such cases you would need to define a variable in your project's settings
module, called ``FOBI_CUSTOM_THEME_DATA``. See the following code as example:
@@ -1742,7 +1743,7 @@ The following HTML5 fields are supported in corresponding bundled plugins:
- placeholder
- type
-With the `fobi.contrib.plugins.form_elements.fields.input` support for
+With the ``fobi.contrib.plugins.form_elements.fields.input`` support for
HTML5 fields is extended to the following fields:
- autocomplete
@@ -1769,7 +1770,7 @@ Dynamic initial values
It's possible to provide a dynamic initial value for any of the text elements.
In order to do that, you should use the build-in context processor or make
your own one. The only requirement is that you should store all values that
-should be exposes in the form as a dict for `fobi_dynamic_values` dictionary
+should be exposes in the form as a dict for ``fobi_dynamic_values`` dictionary
key. Beware, that passing the original request object might be unsafe in
many ways. Currently, a stripped down version of the request object is being
passed as a context variable.
@@ -1793,7 +1794,8 @@ passed as a context variable.
}
}
-In your GUI, you should be refering to the initial values in the following way:
+In your GUI, you should be referring to the initial values in the following
+way:
.. code-block:: html
@@ -1807,21 +1809,21 @@ Currently, the following variables are available in the
- request: Stripped HttpRequest object.
- - request.path: A string representing the full path to the requested page,
- not including the scheme or domain.
+ - request.path: A string representing the full path to the requested
+ page, not including the scheme or domain.
- - request.get_full_path(): Returns the path, plus an appended query string,
- if applicable.
+ - request.get_full_path(): Returns the path, plus an appended query
+ string, if applicable.
- - request.is_secure(): Returns True if the request is secure; that is, if
- it was made with HTTPS.
+ - request.is_secure(): Returns True if the request is secure; that
+ is, if it was made with HTTPS.
- request.is_ajax(): Returns True if the request was made via an
XMLHttpRequest, by checking the HTTP_X_REQUESTED_WITH header for the
string 'XMLHttpRequest'.
- - request.META: A stripped down standard Python dictionary containing the
- available HTTP headers.
+ - request.META: A stripped down standard Python dictionary containing
+ the available HTTP headers.
- HTTP_ACCEPT_ENCODING: Acceptable encodings for the response.
@@ -1833,7 +1835,7 @@ Currently, the following variables are available in the
- HTTP_USER_AGENT: The client’s user-agent string.
- - QUERY_STRING: The query string, as a single (unparsed) string.
+ - QUERY_STRING: The query string, as a single (un-parsed) string.
- REMOTE_ADDR: The IP address of the client.
@@ -1841,9 +1843,9 @@ Currently, the following variables are available in the
- request.user.email:
- - request.user.get_username(): Returns the username for the user. Since
- the User model can be swapped out, you should use this method
- instead of referencing the username attribute directly.
+ - request.user.get_username(): Returns the username for the user.
+ Since the User model can be swapped out, you should use this
+ method instead of referencing the username attribute directly.
- request.user.get_full_name(): Returns the first_name plus the
last_name, with a space in between.
@@ -2038,10 +2040,11 @@ install the test requirements:
Browser tests
-------------
-For browser tests you may choose between Firefox and PhantomJS. PhantomJS is
-faster, Firefox tests tell you more. Both cases require some effort and both
-have disadvantages regarding the installation (although once you have them
-installed they work perfect).
+For browser tests you may choose between Firefox, headless Firefox and
+PhantomJS. PhantomJS is faster, headless Firefox is fast as well, but
+normal Firefox tests tell you more (as you see what exactly happens on the
+screen). Both cases require some effort and both have disadvantages regarding
+the installation (although once you have them installed they work perfect).
Latest versions of Firefox are often not supported by Selenium. Current
version of the Selenium for Python (2.53.6) works fine with Firefox 47.
@@ -2063,10 +2066,31 @@ Set up Firefox 47
FIREFOX_BIN_PATH = '/usr/lib/firefox47/firefox'
- If you set ``FIREFOX_BIN_PATH`` to None, system Firefox would be used.
+ If you set to use system Firefox, remove or comment-out the
+ ``FIREFOX_BIN_PATH`` setting.
After that your Selenium tests would work.
+Set up headless Firefox
+~~~~~~~~~~~~~~~~~~~~~~~
+1. Install ``xvfb`` package which is used to start Firefox in headless mode.
+
+ .. code-block:: sh
+
+ sudo apt-get install xvfb
+
+2. Run the tests using headless Firefox.
+
+ .. code-block:: sh
+
+ ./scripts/runtests.sh
+
+ Or run tox tests using headless Firefox.
+
+ .. code-block:: sh
+
+ ./scripts/tox.sh
+
Setup PhantomJS
~~~~~~~~~~~~~~~
You could also run tests in headless mode (faster). For that you will need
@@ -2088,14 +2112,14 @@ PhantomJS.
PHANTOM_JS_EXECUTABLE_PATH = ""
- If you want to use Firefox for testing, set
- ``PHANTOM_JS_EXECUTABLE_PATH`` to None.
+ If you want to use Firefox for testing, remove or comment-out the
+ ``PHANTOM_JS_EXECUTABLE_PATH`` setting.
Troubleshooting
===============
If you get a ``FormElementPluginDoesNotExist`` or a
``FormHandlerPluginDoesNotExist`` exception, make sure you have listed your
-plugin in the `settings` module of your project.
+plugin in the ``settings`` module of your project.
License
=======
diff --git a/docs/index.rst b/docs/index.rst
index 1136d1e2..e0efc2bf 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -302,8 +302,9 @@ Add the following line to urlpatterns of your `urls` module.
url(r'^fobi/', include('fobi.urls.edit')),
Note, that some plugins require additional URL includes. For instance, if you
-listed the `fobi.contrib.plugins.form_handlers.db_store` form handler plugin
-in the ``INSTALLED_APPS``, you should mention the following in `urls` module.
+listed the ``fobi.contrib.plugins.form_handlers.db_store`` form handler plugin
+in the ``INSTALLED_APPS``, you should mention the following in ``urls``
+module.
.. code-block:: python
@@ -344,8 +345,8 @@ There are several properties, each textarea should have. They are:
- `required` (bool): Flag, which tells us whether the field is required or
optional.
-Let's name that plugin `sample_textarea`. The plugin directory should then have
-the following structure.
+Let's name that plugin ``sample_textarea``. The plugin directory should then
+have the following structure.
.. code-block:: sh
@@ -368,7 +369,7 @@ Define and register the form element plugin
-------------------------------------------
Step by step review of a how to create and register a plugin and plugin
widgets. Note, that `django-fobi` auto-discovers your plugins if you place
-them into a file named `fobi_form_elements.py` of any Django app listed in
+them into a file named ``fobi_form_elements.py`` of any Django app listed in
``INSTALLED_APPS`` of your Django projects' settings module.
path/to/sample_textarea/fobi_form_elements.py
@@ -475,11 +476,11 @@ path/to/sample_textarea/forms.py
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Why to have another file for defining forms? Just to keep the code clean and
less messy, although you could perfectly define all your plugin forms in the
-module `fobi_form_elements.py`, it's recommended to keep it separate.
+module ``fobi_form_elements.py``, it's recommended to keep it separate.
-Take into consideration, that `forms.py` is not an auto-discovered file pattern.
-All your form element plugins should be registered in modules named
-`fobi_form_elements.py`.
+Take into consideration, that ``forms.py`` is not an auto-discovered file
+pattern. All your form element plugins should be registered in modules named
+``fobi_form_elements.py``.
Required imports.
@@ -631,7 +632,7 @@ Do check the source code as example.
Define and register the form handler plugin
-------------------------------------------
-Let's name that plugin `sample_mail`. The plugin directory should then have
+Let's name that plugin ``sample_mail``. The plugin directory should then have
the following structure.
.. code-block:: text
@@ -704,11 +705,11 @@ plugin is configurable, it should have a form.
Why to have another file for defining forms? Just to keep the code clean and
less messy, although you could perfectly define all your plugin forms in the
-module `fobi_form_handlers.py`, it's recommended to keep it separate.
+module ``fobi_form_handlers.py``, it's recommended to keep it separate.
-Take into consideration, that `forms.py` is not an auto-discovered file pattern.
-All your form handler plugins should be registered in modules named
-`fobi_form_handlers.py`.
+Take into consideration, that ``forms.py`` is not an auto-discovered file
+pattern. All your form handler plugins should be registered in modules named
+``fobi_form_handlers.py``.
Required imports.
@@ -837,8 +838,8 @@ existing MailChimp forms into `django-fobi`.
Define and register the form importer plugin
--------------------------------------------
-Let's name that plugin `sample_importer`. The plugin directory should then have
-the following structure.
+Let's name that plugin ``sample_importer``. The plugin directory should then
+have the following structure.
.. code-block:: text
@@ -938,7 +939,7 @@ Required imports.
from django import forms
from django.utils.translation import ugettext_lazy as _
- from sample_service_api import sample_api # Just an imaginary API client
+ from sample_service_api import sample_api # Just an imaginary API client
Defining the form for Sample importer plugin.
@@ -988,7 +989,8 @@ Required imports.
from formtools.wizard.views import SessionWizardView
from path.to.sample_importer.forms import (
- SampleImporterStep1Form, SampleImporterStep2Form
+ SampleImporterStep1Form,
+ SampleImporterStep2Form,
)
Defining the wizard view for Sample importer plugin.
@@ -1076,9 +1078,8 @@ Creating a form callback
Form callbacks are additional hooks, that are executed on various stages of
the form submission.
-Let's place the callback in the `foo` module. The plugin directory should then
-have the following
-structure.
+Let's place the callback in the ``foo`` module. The plugin directory should
+then have the following structure.
.. code-block:: text
@@ -1162,7 +1163,7 @@ themes:
- "Foundation 5" theme
- "Simple" theme in (with editing interface in style of the Django admin)
- "DjangoCMS admin style" theme (which is another simple theme with editing
- interface in style of `djangocms-admin-style`)
+ interface in style of ``djangocms-admin-style``)
Obviously, there are two sorts of views when it comes to editing and viewing
the form.
@@ -1192,7 +1193,7 @@ the "Simple" theme is the best start, since it looks just like django-admin.
Create a new theme
------------------
-Let's place the theme in the `sample_theme` module. The theme directory
+Let's place the theme in the ``sample_theme`` module. The theme directory
should then have the following structure.
.. code-block:: text
@@ -1292,7 +1293,7 @@ Registering the ``SampleTheme`` plugin.
Sometimes you would want to attach additional properties to the theme
in order to use them later in templates (remember, current theme object
-is always available in templates under name `fobi_theme`).
+is always available in templates under name ``fobi_theme``).
For such cases you would need to define a variable in your project's settings
module, called ``FOBI_CUSTOM_THEME_DATA``. See the following code as example:
@@ -1742,7 +1743,7 @@ The following HTML5 fields are supported in corresponding bundled plugins:
- placeholder
- type
-With the `fobi.contrib.plugins.form_elements.fields.input` support for
+With the ``fobi.contrib.plugins.form_elements.fields.input`` support for
HTML5 fields is extended to the following fields:
- autocomplete
@@ -1769,7 +1770,7 @@ Dynamic initial values
It's possible to provide a dynamic initial value for any of the text elements.
In order to do that, you should use the build-in context processor or make
your own one. The only requirement is that you should store all values that
-should be exposes in the form as a dict for `fobi_dynamic_values` dictionary
+should be exposes in the form as a dict for ``fobi_dynamic_values`` dictionary
key. Beware, that passing the original request object might be unsafe in
many ways. Currently, a stripped down version of the request object is being
passed as a context variable.
@@ -1793,7 +1794,8 @@ passed as a context variable.
}
}
-In your GUI, you should be refering to the initial values in the following way:
+In your GUI, you should be referring to the initial values in the following
+way:
.. code-block:: html
@@ -1807,21 +1809,21 @@ Currently, the following variables are available in the
- request: Stripped HttpRequest object.
- - request.path: A string representing the full path to the requested page,
- not including the scheme or domain.
+ - request.path: A string representing the full path to the requested
+ page, not including the scheme or domain.
- - request.get_full_path(): Returns the path, plus an appended query string,
- if applicable.
+ - request.get_full_path(): Returns the path, plus an appended query
+ string, if applicable.
- - request.is_secure(): Returns True if the request is secure; that is, if
- it was made with HTTPS.
+ - request.is_secure(): Returns True if the request is secure; that
+ is, if it was made with HTTPS.
- request.is_ajax(): Returns True if the request was made via an
XMLHttpRequest, by checking the HTTP_X_REQUESTED_WITH header for the
string 'XMLHttpRequest'.
- - request.META: A stripped down standard Python dictionary containing the
- available HTTP headers.
+ - request.META: A stripped down standard Python dictionary containing
+ the available HTTP headers.
- HTTP_ACCEPT_ENCODING: Acceptable encodings for the response.
@@ -1833,7 +1835,7 @@ Currently, the following variables are available in the
- HTTP_USER_AGENT: The client’s user-agent string.
- - QUERY_STRING: The query string, as a single (unparsed) string.
+ - QUERY_STRING: The query string, as a single (un-parsed) string.
- REMOTE_ADDR: The IP address of the client.
@@ -1841,9 +1843,9 @@ Currently, the following variables are available in the
- request.user.email:
- - request.user.get_username(): Returns the username for the user. Since
- the User model can be swapped out, you should use this method
- instead of referencing the username attribute directly.
+ - request.user.get_username(): Returns the username for the user.
+ Since the User model can be swapped out, you should use this
+ method instead of referencing the username attribute directly.
- request.user.get_full_name(): Returns the first_name plus the
last_name, with a space in between.
@@ -2038,10 +2040,11 @@ install the test requirements:
Browser tests
-------------
-For browser tests you may choose between Firefox and PhantomJS. PhantomJS is
-faster, Firefox tests tell you more. Both cases require some effort and both
-have disadvantages regarding the installation (although once you have them
-installed they work perfect).
+For browser tests you may choose between Firefox, headless Firefox and
+PhantomJS. PhantomJS is faster, headless Firefox is fast as well, but
+normal Firefox tests tell you more (as you see what exactly happens on the
+screen). Both cases require some effort and both have disadvantages regarding
+the installation (although once you have them installed they work perfect).
Latest versions of Firefox are often not supported by Selenium. Current
version of the Selenium for Python (2.53.6) works fine with Firefox 47.
@@ -2063,10 +2066,31 @@ Set up Firefox 47
FIREFOX_BIN_PATH = '/usr/lib/firefox47/firefox'
- If you set ``FIREFOX_BIN_PATH`` to None, system Firefox would be used.
+ If you set to use system Firefox, remove or comment-out the
+ ``FIREFOX_BIN_PATH`` setting.
After that your Selenium tests would work.
+Set up headless Firefox
+~~~~~~~~~~~~~~~~~~~~~~~
+1. Install ``xvfb`` package which is used to start Firefox in headless mode.
+
+ .. code-block:: sh
+
+ sudo apt-get install xvfb
+
+2. Run the tests using headless Firefox.
+
+ .. code-block:: sh
+
+ ./scripts/runtests.sh
+
+ Or run tox tests using headless Firefox.
+
+ .. code-block:: sh
+
+ ./scripts/tox.sh
+
Setup PhantomJS
~~~~~~~~~~~~~~~
You could also run tests in headless mode (faster). For that you will need
@@ -2088,14 +2112,14 @@ PhantomJS.
PHANTOM_JS_EXECUTABLE_PATH = ""
- If you want to use Firefox for testing, set
- ``PHANTOM_JS_EXECUTABLE_PATH`` to None.
+ If you want to use Firefox for testing, remove or comment-out the
+ ``PHANTOM_JS_EXECUTABLE_PATH`` setting.
Troubleshooting
===============
If you get a ``FormElementPluginDoesNotExist`` or a
``FormHandlerPluginDoesNotExist`` exception, make sure you have listed your
-plugin in the `settings` module of your project.
+plugin in the ``settings`` module of your project.
License
=======
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index 4084fb25..554797bc 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -16,14 +16,14 @@ Installation and configuration
------------------------------
Install the package in your environment.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. code-block:: none
+.. code-block:: sh
pip install django-fobi
INSTALLED_APPS
^^^^^^^^^^^^^^
Add ``fobi`` core and the plugins to the ``INSTALLED_APPS`` of the your
-`settings` module.
+``settings`` module.
1. The core.
@@ -47,7 +47,7 @@ Add ``fobi`` core and the plugins to the ``INSTALLED_APPS`` of the your
`_
would require additional packages to be installed. If so, make sure to have
installed and configured those dependencies prior adding the dependant
- add-ons to the `settings` module.
+ add-ons to the ``settings`` module.
.. code-block:: python
@@ -82,7 +82,7 @@ Add ``fobi`` core and the plugins to the ``INSTALLED_APPS`` of the your
.. code-block:: python
- 'easy_thumbnails', # Required by `content_image` plugin
+ 'easy_thumbnails', # Required by `content_image` plugin
'fobi.contrib.plugins.form_elements.content.content_image',
'fobi.contrib.plugins.form_elements.content.content_text',
'fobi.contrib.plugins.form_elements.content.content_video',
@@ -145,7 +145,7 @@ Putting all together, you would have something like this.
'fobi.contrib.plugins.form_elements.fields.url',
# Form element plugins
- 'easy_thumbnails', # Required by `content_image` plugin
+ 'easy_thumbnails', # Required by ``content_image`` plugin
'fobi.contrib.plugins.form_elements.content.content_image',
'fobi.contrib.plugins.form_elements.content.content_text',
'fobi.contrib.plugins.form_elements.content.content_video',
@@ -162,21 +162,21 @@ TEMPLATE_CONTEXT_PROCESSORS
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Add ``django.core.context_processors.request`` and
``fobi.context_processors.theme`` to ``TEMPLATE_CONTEXT_PROCESSORS`` of
-your `settings` module.
+your ``settings`` module.
.. code-block:: python
TEMPLATE_CONTEXT_PROCESSORS = (
# ...
"django.core.context_processors.request",
- "fobi.context_processors.theme", # Obligatory
- "fobi.context_processors.dynamic_values", # Optional
+ "fobi.context_processors.theme", # Obligatory
+ "fobi.context_processors.dynamic_values", # Optional
# ...
)
urlpatterns
^^^^^^^^^^^
-Add the following line to ``urlpatterns`` of your `urls` module.
+Add the following line to ``urlpatterns`` of your ``urls`` module.
.. code-block:: python
@@ -201,21 +201,21 @@ Update the database
1. First you should be syncing/migrating the database. Depending on your
Django version and migration app, this step may vary. Typically as follows:
-.. code-block:: none
+.. code-block:: sh
- $ ./manage.py syncdb
- $ ./manage.py migrate --fake-initial
+ ./manage.py syncdb
+ ./manage.py migrate --fake-initial
2. Sync installed ``fobi`` plugins. Go to terminal and type the following
command.
-.. code-block:: none
+.. code-block:: sh
- $ ./manage.py fobi_sync_plugins
+ ./manage.py fobi_sync_plugins
Specify the active theme
^^^^^^^^^^^^^^^^^^^^^^^^
-Specify the default theme in your `settings` module.
+Specify the default theme in your ``settings`` module.
.. code-block:: python
diff --git a/scripts/runtests.sh b/scripts/runtests.sh
new file mode 100755
index 00000000..d82c3774
--- /dev/null
+++ b/scripts/runtests.sh
@@ -0,0 +1 @@
+xvfb-run python runtests.py
diff --git a/scripts/tox.sh b/scripts/tox.sh
new file mode 100755
index 00000000..813a3044
--- /dev/null
+++ b/scripts/tox.sh
@@ -0,0 +1 @@
+xvfb-run python toxtests.py
diff --git a/setup.py b/setup.py
index b9e61e51..4e329c5e 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ import sys
from distutils.version import LooseVersion
from setuptools import setup, find_packages
-version = '0.10.6'
+version = '0.10.7'
# ***************************************************************************
# ************************** Python version *********************************
@@ -78,7 +78,7 @@ except Exception as err:
try:
readme = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read()
screenshots = open(
- os.path.join(os.path.dirname(__file__), 'SCREENSHOTS.rst')
+ os.path.join(os.path.dirname(__file__), 'docs/screenshots.rst.distrib')
).read()
screenshots = screenshots.replace(
'.. image:: _static',
diff --git a/src/fobi/__init__.py b/src/fobi/__init__.py
index 69733cf5..748ba227 100644
--- a/src/fobi/__init__.py
+++ b/src/fobi/__init__.py
@@ -1,6 +1,6 @@
__title__ = 'django-fobi'
-__version__ = '0.10.6'
-__build__ = 0x000079
+__version__ = '0.10.7'
+__build__ = 0x00007a
__author__ = 'Artur Barseghyan '
__copyright__ = '2014-2017 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
diff --git a/src/fobi/admin.py b/src/fobi/admin.py
index 4b1dfa87..c9aa113b 100644
--- a/src/fobi/admin.py
+++ b/src/fobi/admin.py
@@ -81,7 +81,7 @@ def base_bulk_change_plugins(PluginForm, named_url, modeladmin, request,
post = dict(request.POST)
if selected:
post['selected_plugins'] = ','.join(selected)
- if 'POST' == request.method:
+ if request.method == 'POST':
form = PluginForm(
data=post,
files=request.FILES,
@@ -455,7 +455,7 @@ class BasePluginModelAdmin(admin.ModelAdmin):
This is where the data is actually processed.
"""
changelist_named_url = self._get_changelist_named_url()
- if 'POST' == request.method:
+ if request.method == 'POST':
form_cls = self._get_bulk_change_form_class()
form = form_cls(
data=request.POST,
diff --git a/src/fobi/contrib/plugins/form_handlers/db_store/fobi_form_handlers.py b/src/fobi/contrib/plugins/form_handlers/db_store/fobi_form_handlers.py
index 5895ad42..a8b64099 100644
--- a/src/fobi/contrib/plugins/form_handlers/db_store/fobi_form_handlers.py
+++ b/src/fobi/contrib/plugins/form_handlers/db_store/fobi_form_handlers.py
@@ -2,9 +2,10 @@ import datetime
import simplejson as json
-from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
+from nine.versions import DJANGO_GTE_1_10
+
from fobi.base import (
# General
get_processed_form_data,
@@ -24,6 +25,11 @@ from fobi.helpers import get_form_element_entries_for_form_wizard_entry
from . import UID
from .models import SavedFormDataEntry, SavedFormWizardDataEntry
+if DJANGO_GTE_1_10:
+ from django.urls import reverse
+else:
+ from django.core.urlresolvers import reverse
+
__title__ = 'fobi.contrib.plugins.form_handlers.db_store.fobi_form_handlers'
__author__ = 'Artur Barseghyan '
__copyright__ = '2014-2017 Artur Barseghyan'
diff --git a/src/fobi/contrib/plugins/form_importers/mailchimp_importer/views.py b/src/fobi/contrib/plugins/form_importers/mailchimp_importer/views.py
index daa37006..a3ce6234 100644
--- a/src/fobi/contrib/plugins/form_importers/mailchimp_importer/views.py
+++ b/src/fobi/contrib/plugins/form_importers/mailchimp_importer/views.py
@@ -1,16 +1,22 @@
import logging
-import mailchimp
-
from django.contrib import messages
-from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
+import mailchimp
+
from fobi.wizard import SessionWizardView
+from nine.versions import DJANGO_GTE_1_10
+
from .forms import MailchimpAPIKeyForm, MailchimpListIDForm
+if DJANGO_GTE_1_10:
+ from django.urls import reverse
+else:
+ from django.core.urlresolvers import reverse
+
__title__ = 'fobi.contrib.plugins.form_importers.mailchimp_importer.views'
__author__ = 'Artur Barseghyan '
__copyright__ = '2014-2017 Artur Barseghyan'
diff --git a/src/fobi/dynamic.py b/src/fobi/dynamic.py
index 35f01a09..2e0be25f 100644
--- a/src/fobi/dynamic.py
+++ b/src/fobi/dynamic.py
@@ -1,21 +1,28 @@
-from six import with_metaclass
-
-from django.core.urlresolvers import reverse
from django.forms.forms import BaseForm
from django.forms.widgets import media_property
from django.http import HttpResponseRedirect
-from nine.versions import DJANGO_GTE_1_7, DJANGO_GTE_1_8
+from nine.versions import (
+ DJANGO_GTE_1_7,
+ DJANGO_GTE_1_8,
+ DJANGO_GTE_1_10,
+)
+
+from six import with_metaclass
from .constants import WIZARD_TYPE_COOKIE, WIZARD_TYPE_SESSION
if DJANGO_GTE_1_8:
from formtools.wizard.views import (
- WizardView, SessionWizardView, CookieWizardView
+ CookieWizardView,
+ SessionWizardView,
+ WizardView,
)
else:
from django.contrib.formtools.wizard.views import (
- WizardView, SessionWizardView, CookieWizardView
+ CookieWizardView,
+ SessionWizardView,
+ WizardView,
)
if DJANGO_GTE_1_7:
@@ -23,6 +30,11 @@ if DJANGO_GTE_1_7:
else:
from django.utils.datastructures import SortedDict as OrderedDict
+if DJANGO_GTE_1_10:
+ from django.urls import reverse
+else:
+ from django.core.urlresolvers import reverse
+
__title__ = 'fobi.dynamic'
__author__ = 'Artur Barseghyan '
__copyright__ = '2014-2017 Artur Barseghyan'
diff --git a/src/fobi/form_importers.py b/src/fobi/form_importers.py
index d2d3135b..39f0ca0f 100644
--- a/src/fobi/form_importers.py
+++ b/src/fobi/form_importers.py
@@ -1,12 +1,17 @@
-from six import text_type
+from nine.versions import DJANGO_GTE_1_10
import simplejson as json
-from django.core.urlresolvers import reverse
+from six import text_type
from .base import BaseRegistry
from .discover import autodiscover
+if DJANGO_GTE_1_10:
+ from django.urls import reverse
+else:
+ from django.core.urlresolvers import reverse
+
__title__ = 'fobi.form_importers'
__author__ = 'Artur Barseghyan '
__copyright__ = '2014-2017 Artur Barseghyan'
diff --git a/src/fobi/helpers.py b/src/fobi/helpers.py
index 51bd6a62..a97a570d 100644
--- a/src/fobi/helpers.py
+++ b/src/fobi/helpers.py
@@ -3,47 +3,50 @@ Helpers module. This module can be safely imported from any fobi (sub)module,
since it never imports from any of the fobi (sub)modules (except for the
`fobi.constants` and `fobi.exceptions` modules).
"""
-import os
import glob
import logging
-import uuid
+import os
import shutil
-
-from six import text_type, PY3
-
-import simplejson as json
-
-from django.conf import settings
-from django.core.urlresolvers import reverse
-from django.core.files.base import File
-from django.contrib.contenttypes.models import ContentType
-from django.db.utils import DatabaseError
-from django.utils.encoding import force_text
-from django.utils.html import format_html_join
-from django import forms
-from django.utils.translation import ugettext_lazy as _
-from django.contrib.auth.models import AnonymousUser
-from django.test.client import RequestFactory
-from django.http import HttpResponse
+import uuid
from autoslug.settings import slugify
-from nine.user import User
-from nine.versions import DJANGO_GTE_1_7
+from django import forms
+from django.conf import settings
+from django.contrib.auth.models import AnonymousUser
+# from django.contrib.contenttypes.models import ContentType
+from django.core.files.base import File
+# from django.db.utils import DatabaseError
+from django.http import HttpResponse
+from django.test.client import RequestFactory
+from django.utils.encoding import force_text
+from django.utils.html import format_html_join
+from django.utils.translation import ugettext_lazy as _
-from fobi.constants import (
- SUBMIT_VALUE_AS_VAL,
+from nine.user import User
+from nine.versions import DJANGO_GTE_1_7, DJANGO_GTE_1_10
+
+import simplejson as json
+
+from six import text_type, PY3
+
+from .constants import (
+ SUBMIT_VALUE_AS_MIX,
SUBMIT_VALUE_AS_REPR,
- SUBMIT_VALUE_AS_MIX
+ SUBMIT_VALUE_AS_VAL,
)
-from fobi.exceptions import ImproperlyConfigured
+from .exceptions import ImproperlyConfigured
if DJANGO_GTE_1_7:
import django.apps
-
else:
from django.db import models
+if DJANGO_GTE_1_10:
+ from django.urls import reverse
+else:
+ from django.core.urlresolvers import reverse
+
__title__ = 'fobi.helpers'
__author__ = 'Artur Barseghyan '
__copyright__ = '2014-2017 Artur Barseghyan'
@@ -873,7 +876,7 @@ def get_wizard_form_field_value_from_request(request,
return value
# Then try POST
- if 'POST' == request.method:
+ if request.method == 'POST':
value = get_wizard_form_field_value_from_post(
request,
wizard_view_name,
@@ -884,7 +887,7 @@ def get_wizard_form_field_value_from_request(request,
else:
# First try POST
- if 'POST' == request.method:
+ if request.method == 'POST':
value = get_wizard_form_field_value_from_post(
request,
wizard_view_name,
diff --git a/src/fobi/integration/helpers.py b/src/fobi/integration/helpers.py
index 8263b568..60cf0a1b 100644
--- a/src/fobi/integration/helpers.py
+++ b/src/fobi/integration/helpers.py
@@ -1,4 +1,4 @@
-from fobi.base import get_theme
+from ..base import get_theme
__title__ = 'fobi.integration.helpers'
__author__ = 'Artur Barseghyan '
diff --git a/src/fobi/integration/processors.py b/src/fobi/integration/processors.py
index 68d9b438..e45a8653 100644
--- a/src/fobi/integration/processors.py
+++ b/src/fobi/integration/processors.py
@@ -5,18 +5,22 @@ from django.template import RequestContext
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
-from fobi.base import (
- fire_form_callbacks, run_form_handlers,
- submit_plugin_form_data, get_theme
+from ..base import (
+ fire_form_callbacks,
+ get_theme,
+ run_form_handlers,
+ submit_plugin_form_data,
)
-from fobi.constants import (
- CALLBACK_BEFORE_FORM_VALIDATION, CALLBACK_FORM_INVALID,
- CALLBACK_FORM_VALID_BEFORE_SUBMIT_PLUGIN_FORM_DATA, CALLBACK_FORM_VALID,
- CALLBACK_FORM_VALID_AFTER_FORM_HANDLERS
+from ..constants import (
+ CALLBACK_BEFORE_FORM_VALIDATION,
+ CALLBACK_FORM_INVALID,
+ CALLBACK_FORM_VALID,
+ CALLBACK_FORM_VALID_AFTER_FORM_HANDLERS,
+ CALLBACK_FORM_VALID_BEFORE_SUBMIT_PLUGIN_FORM_DATA,
)
-from fobi.dynamic import assemble_form_class
-from fobi.exceptions import ImproperlyConfigured
-from fobi.settings import GET_PARAM_INITIAL_DATA
+from ..dynamic import assemble_form_class
+from ..exceptions import ImproperlyConfigured
+from ..settings import GET_PARAM_INITIAL_DATA
__title__ = 'fobi.integration.processors'
__author__ = 'Artur Barseghyan '
@@ -70,6 +74,7 @@ class IntegrationProcessor(object):
)
def get_context_data(self, request, instance, **kwargs):
+ """Get context data."""
context = {
'form_entry': instance.form_entry,
}
@@ -77,12 +82,15 @@ class IntegrationProcessor(object):
return context
def get_form_template_name(self, request, instance):
+ """Get form template name."""
return instance.form_template_name or None
def get_success_page_template_name(self, request, instance):
+ """Get succes page template name."""
return instance.success_page_template_name or None
def get_login_required_template_name(self, request, instance):
+ """Get login required template name."""
return self.login_required_template_name or None
def _process_form(self, request, instance, **kwargs):
@@ -121,7 +129,7 @@ class IntegrationProcessor(object):
request=request
)
- if 'POST' == request.method:
+ if request.method == 'POST':
form = FormClass(request.POST, request.FILES)
# Fire pre form validation callbacks
@@ -133,8 +141,7 @@ class IntegrationProcessor(object):
)
if form.is_valid():
- # Fire form valid callbacks, before handling sufrom
- # django.http import HttpResponseRedirectbmitted plugin
+ # Fire form valid callbacks, before handling submitted plugin
# form data
form = fire_form_callbacks(
form_entry=instance.form_entry,
diff --git a/src/fobi/models.py b/src/fobi/models.py
index 4533054a..cdea0001 100644
--- a/src/fobi/models.py
+++ b/src/fobi/models.py
@@ -2,13 +2,14 @@ from __future__ import absolute_import
import logging
+from autoslug import AutoSlugField
+
from django.conf import settings
from django.contrib.auth.models import Group
-from django.core.urlresolvers import reverse
from django.db import models
from django.utils.translation import ugettext_lazy as _
-from autoslug import AutoSlugField
+from nine.versions import DJANGO_GTE_1_10
from six import python_2_unicode_compatible
@@ -18,10 +19,15 @@ from .base import (
form_wizard_handler_plugin_registry,
get_registered_form_element_plugins,
get_registered_form_handler_plugins,
- get_registered_form_wizard_handler_plugins
+ get_registered_form_wizard_handler_plugins,
)
from .constants import WIZARD_TYPES, DEFAULT_WIZARD_TYPE
+if DJANGO_GTE_1_10:
+ from django.urls import reverse
+else:
+ from django.core.urlresolvers import reverse
+
__title__ = 'fobi.models'
__author__ = 'Artur Barseghyan '
__copyright__ = '2014-2017 Artur Barseghyan'
diff --git a/src/fobi/templatetags/fobi_tags.py b/src/fobi/templatetags/fobi_tags.py
index c8dfce81..d2282e19 100644
--- a/src/fobi/templatetags/fobi_tags.py
+++ b/src/fobi/templatetags/fobi_tags.py
@@ -30,7 +30,7 @@ __all__ = (
THEME = get_theme(request=None, as_instance=True)
-REGISTER = Library()
+register = Library()
# *****************************************************************************
# *****************************************************************************
@@ -63,7 +63,7 @@ class GetFobiPluginNode(Node):
return ''
-@REGISTER.tag
+@register.tag
def get_fobi_plugin(parser, token):
"""Get the plugin.
@@ -126,7 +126,7 @@ class GetFobiFormHandlerPluginCustomActionsNode(Node):
return ''
-@REGISTER.tag
+@register.tag
def get_fobi_form_handler_plugin_custom_actions(parser, token):
"""Get the form handler plugin custom actions.
@@ -192,7 +192,7 @@ class GetFobiFormWizardHandlerPluginCustomActionsNode(Node):
return ''
-@REGISTER.tag
+@register.tag
def get_fobi_form_wizard_handler_plugin_custom_actions(parser, token):
"""Get the form wizard handler plugin custom actions.
@@ -275,12 +275,12 @@ def render_auth_link(context):
}
-REGISTER.inclusion_tag(
+register.inclusion_tag(
'fobi/snippets/render_auth_link.html', takes_context=True
)(render_auth_link)
-@REGISTER.inclusion_tag(THEME.forms_list_template, takes_context=True)
+@register.inclusion_tag(THEME.forms_list_template, takes_context=True)
def render_fobi_forms_list(context, queryset, *args, **kwargs):
"""Render the list of fobi forms.
@@ -366,7 +366,7 @@ class HasEditFormEntryPermissionsNode(Node):
return False
-@REGISTER.tag
+@register.tag
def has_edit_form_entry_permissions(parser, token):
"""Checks the permissions
@@ -456,7 +456,7 @@ class GetFormFieldTypeNode(Node):
return ''
-@REGISTER.tag
+@register.tag
def get_form_field_type(parser, token):
"""Get form field type.
@@ -515,7 +515,7 @@ class GetFormHiddenFieldsErrorsNode(Node):
return ''
-@REGISTER.tag
+@register.tag
def get_form_hidden_fields_errors(parser, token):
"""Get form hidden fields errors.
diff --git a/src/fobi/templatetags/future_compat.py b/src/fobi/templatetags/future_compat.py
index 3053061f..3d16a3b2 100644
--- a/src/fobi/templatetags/future_compat.py
+++ b/src/fobi/templatetags/future_compat.py
@@ -20,7 +20,7 @@ except ImportError:
from django.utils.safestring import mark_safe, EscapeData, SafeData
from django.utils.timezone import template_localtime
- REGISTER = Library()
+ register = Library()
def render_value_in_context(value, context):
"""Render value in context.
@@ -56,7 +56,7 @@ except ImportError:
return render_value_in_context(value, context)
return ''
- @REGISTER.tag
+ @register.tag
def firstof(parser, token, escape=False):
"""Outputs the first variable passed that is not False.
diff --git a/src/fobi/tests/test_browser_build_dynamic_forms.py b/src/fobi/tests/test_browser_build_dynamic_forms.py
index 57fde797..4469ec8c 100644
--- a/src/fobi/tests/test_browser_build_dynamic_forms.py
+++ b/src/fobi/tests/test_browser_build_dynamic_forms.py
@@ -11,12 +11,13 @@ from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import WebDriverException
from django.core.management import call_command
-from django.core.urlresolvers import reverse
from django.test import LiveServerTestCase
from django.conf import settings
from fobi.models import FormEntry
+from nine.versions import DJANGO_GTE_1_10
+
from . import constants
from .base import print_info, skip
from .data import (
@@ -31,6 +32,10 @@ from .helpers import (
phantom_js_clean_up
)
+if DJANGO_GTE_1_10:
+ from django.urls import reverse
+else:
+ from django.core.urlresolvers import reverse
__title__ = 'fobi.tests.test_browser_build_dynamic_forms'
__author__ = 'Artur Barseghyan '
diff --git a/src/fobi/utils.py b/src/fobi/utils.py
index 7f136ac8..d6b385a5 100644
--- a/src/fobi/utils.py
+++ b/src/fobi/utils.py
@@ -3,18 +3,19 @@ Another helper module. This module can NOT be safely imported from any fobi
(sub)module - thus should be imported carefully.
"""
import datetime
-import os
import logging
-
-from six import PY3
+import os
from django.conf import settings
from django.contrib import messages
-from django.core.urlresolvers import reverse
from django.forms.widgets import TextInput
from django.utils.encoding import force_text
from django.utils.translation import ugettext, ugettext_lazy as _
+from nine.versions import DJANGO_GTE_1_10
+
+from six import PY3
+
from .base import (
form_element_plugin_registry,
form_handler_plugin_registry,
@@ -42,6 +43,11 @@ from .models import (
)
from .settings import RESTRICT_PLUGIN_ACCESS, DEBUG, WIZARD_FILES_UPLOAD_DIR
+if DJANGO_GTE_1_10:
+ from django.urls import reverse
+else:
+ from django.core.urlresolvers import reverse
+
__title__ = 'fobi.utils'
__author__ = 'Artur Barseghyan '
__copyright__ = '2014-2017 Artur Barseghyan'
diff --git a/src/fobi/views.py b/src/fobi/views.py
index 7120e608..3daae4a8 100644
--- a/src/fobi/views.py
+++ b/src/fobi/views.py
@@ -15,7 +15,6 @@ from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.core.exceptions import ObjectDoesNotExist
from django.core.files.storage import FileSystemStorage
-from django.core.urlresolvers import reverse
from django.forms import ValidationError
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import redirect
@@ -87,7 +86,9 @@ from .wizard import DynamicSessionWizardView, DynamicCookieWizardView
if versions.DJANGO_GTE_1_10:
from django.shortcuts import render
+ from django.urls import reverse
else:
+ from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response
if versions.DJANGO_GTE_1_8:
@@ -352,7 +353,7 @@ def create_form_entry(request, theme=None, template_name=None):
:param str template_name:
:return django.http.HttpResponse:
"""
- if 'POST' == request.method:
+ if request.method == 'POST':
form = FormEntryForm(request.POST, request.FILES, request=request)
if form.is_valid():
form_entry = form.save(commit=False)
@@ -429,7 +430,7 @@ def edit_form_entry(request, form_entry_id, theme=None, template_name=None):
except ObjectDoesNotExist as err:
raise Http404(ugettext("Form entry not found."))
- if 'POST' == request.method:
+ if request.method == 'POST':
# The form entry form (does not contain form elements)
form = FormEntryForm(request.POST, request.FILES, instance=form_entry,
request=request)
@@ -672,7 +673,7 @@ def add_form_element_entry(request,
save_object = True
# If POST
- elif 'POST' == request.method:
+ elif request.method == 'POST':
# If element has a form
form = form_element_plugin.get_initialised_create_form_or_404(
data=request.POST,
@@ -759,7 +760,7 @@ def edit_form_element_entry(request,
:param django.http.HttpRequest request:
:param int form_element_entry_id:
- :param fobi.base.BaseTheme: Theme instance.
+ :param fobi.base.BaseTheme theme: Theme instance.
:param string template_name:
:return django.http.HttpResponse:
"""
@@ -787,7 +788,7 @@ def edit_form_element_entry(request,
)
return redirect('fobi.edit_form_entry', form_entry_id=form_entry.pk)
- elif 'POST' == request.method:
+ elif request.method == 'POST':
form = form_element_plugin.get_initialised_edit_form_or_404(
data=request.POST,
files=request.FILES
@@ -942,7 +943,7 @@ def add_form_handler_entry(request,
if not form_handler_plugin_form_cls:
save_object = True
- elif 'POST' == request.method:
+ elif request.method == 'POST':
form = form_handler_plugin.get_initialised_create_form_or_404(
data=request.POST,
files=request.FILES
@@ -1042,7 +1043,7 @@ def edit_form_handler_entry(request,
)
return redirect('fobi.edit_form_entry', form_entry_id=form_entry.pk)
- elif 'POST' == request.method:
+ elif request.method == 'POST':
form = form_handler_plugin.get_initialised_edit_form_or_404(
data=request.POST,
files=request.FILES
@@ -1146,7 +1147,7 @@ def create_form_wizard_entry(request, theme=None, template_name=None):
:param str template_name:
:return django.http.HttpResponse:
"""
- if 'POST' == request.method:
+ if request.method == 'POST':
form = FormWizardEntryForm(request.POST,
request.FILES,
request=request)
@@ -1231,7 +1232,7 @@ def edit_form_wizard_entry(request, form_wizard_entry_id, theme=None,
except ObjectDoesNotExist as err:
raise Http404(ugettext("Form wizard entry not found."))
- if 'POST' == request.method:
+ if request.method == 'POST':
# The form entry form (does not contain form elements)
form = FormWizardEntryForm(request.POST, request.FILES,
instance=form_wizard_entry,
@@ -1952,7 +1953,7 @@ def add_form_wizard_handler_entry(request,
if not form_wizard_handler_plugin_form_cls:
save_object = True
- elif 'POST' == request.method:
+ elif request.method == 'POST':
form = form_wizard_handler_plugin.get_initialised_create_form_or_404(
data=request.POST,
files=request.FILES
@@ -2059,7 +2060,7 @@ def edit_form_wizard_handler_entry(request,
form_wizard_entry_id=form_wizard_entry.pk
)
- elif 'POST' == request.method:
+ elif request.method == 'POST':
form = form_wizard_handler_plugin.get_initialised_edit_form_or_404(
data=request.POST,
files=request.FILES
@@ -2176,7 +2177,7 @@ def view_form_entry(request, form_entry_slug, theme=None, template_name=None):
request=request
)
- if 'POST' == request.method:
+ if request.method == 'POST':
form = form_cls(request.POST, request.FILES)
# Fire pre form validation callbacks
@@ -2405,7 +2406,7 @@ def import_form_entry(request, template_name=None):
:param string template_name:
:return django.http.HttpResponse:
"""
- if 'POST' == request.method:
+ if request.method == 'POST':
form = ImportFormEntryForm(request.POST, request.FILES)
if form.is_valid():
@@ -2610,7 +2611,7 @@ def import_form_wizard_entry(request, template_name=None):
:param string template_name:
:return django.http.HttpResponse:
"""
- if 'POST' == request.method:
+ if request.method == 'POST':
form = ImportFormWizardEntryForm(request.POST, request.FILES)
if form.is_valid():
diff --git a/src/fobi/wizard/views/dynamic.py b/src/fobi/wizard/views/dynamic.py
index fe029cb0..f333a96d 100644
--- a/src/fobi/wizard/views/dynamic.py
+++ b/src/fobi/wizard/views/dynamic.py
@@ -4,7 +4,6 @@ import re
from django import forms
from django.shortcuts import redirect
-from django.core.urlresolvers import reverse
from django.forms import formsets, ValidationError
from django.views.generic import TemplateView
from django.utils.decorators import classonlymethod
@@ -24,6 +23,11 @@ else:
)
from django.contrib.formtools.wizard.forms import ManagementForm
+if versions.DJANGO_GTE_1_10:
+ from django.urls import reverse
+else:
+ from django.core.urlresolvers import reverse
+
logger = logging.getLogger(__name__)
__all__ = (
diff --git a/toxtests.py b/toxtests.py
new file mode 100644
index 00000000..c0bc55ef
--- /dev/null
+++ b/toxtests.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+from tox.session import main
+
+if __name__ == "__main__":
+ main()