Skip to content
This repository has been archived by the owner on Feb 7, 2019. It is now read-only.

Commit

Permalink
Merge pull request #140 from maennel/django19_110_111-compatibility
Browse files Browse the repository at this point in the history
Django1.9, 1.10 and 1.11 compatibility

Support for current versions of Django (1.10 and 1.11) is added via this PR. 
Since the test base has been taken over in an unmodified way, we ensure feature-equivalence compared to previous versions of CleanerVersion (everything pre-2.x).
  • Loading branch information
maennel authored Sep 18, 2017
2 parents c9c9bf0 + cd8a416 commit 73bf78e
Show file tree
Hide file tree
Showing 25 changed files with 1,025 additions and 806 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ sqlite.db
# dev_no_debug.py imports local.py and disables Django-debugging
cleanerversion/settings/dev_no_debug.py
cleanerversion/settings/*_local.py

bin/
share/
include/
lib/
pip-selfcheck.json
11 changes: 7 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ python:
- "3.6"

env:
- TOX_ENV=py27-django18-pg
- TOX_ENV=py27-django18-sqlite
- TOX_ENV=py36-django18-pg
- TOX_ENV=py36-django18-sqlite
- TOX_ENV=django19-pg
- TOX_ENV=django19-sqlite
- TOX_ENV=django110-pg
- TOX_ENV=django110-sqlite
- TOX_ENV=django111-pg
- TOX_ENV=django111-sqlite


# Enable PostgreSQL usage
addons:
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Local Testing
To test locally on the various environments that are tested by Travis, you can use `tox <https://testrun.org/tox/latest/>`_.
To do this, these dependencies must be installed:

* python 2.7 and python 3.4
* python 2.7 and python 3.6
* tox (if you're using pip, you can install tox with ``pip install tox``)
* postgresql 9.3.x

Expand Down
10 changes: 7 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,22 @@ Prerequisites

This code was tested with the following technical components

* Python 2.7 & 3.4
* Django 1.8
* Python 2.7 & 3.6
* Django 1.9 - 1.11
* PostgreSQL 9.3.4 & SQLite3

Older Django versions
=====================
CleanerVersion was originally written for Django 1.6.
CleanerVersion was originally written for Django 1.6 and has now been ported up to Django 1.11.

CleanerVersion 2.x releases are compatible with Django 1.9, 1.10 and 1.11.

Old packages compatible with older Django releases:

* Django 1.6 and 1.7: https://pypi.python.org/pypi/CleanerVersion/1.5.4

* Django 1.8: https://pypi.python.org/pypi/CleanerVersion/1.6.2


Documentation
=============
Expand Down
7 changes: 7 additions & 0 deletions cleanerversion/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
VERSION = (2, 0, 0)

def get_version(positions=None):
version = VERSION
if positions and isinstance(positions, int):
version = VERSION[:positions]
version = (str(v) for v in version)
return '.'.join(version)
23 changes: 16 additions & 7 deletions cleanerversion/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
"""

from __future__ import absolute_import
from django.utils.crypto import get_random_string

import os

from django.utils.crypto import get_random_string

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)) + '/..')

# SECURITY WARNING: keep the secret key used in production secret!
Expand All @@ -20,9 +22,17 @@

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = True


TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': ['django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages'],
},
},
]

ALLOWED_HOSTS = []

Expand Down Expand Up @@ -64,7 +74,7 @@
'django.contrib.messages',
'django.contrib.staticfiles',
'versions',
'versions_tests',
'versions_tests.apps.VersionsTestsConfig',
)

MIDDLEWARE_CLASSES = (
Expand All @@ -85,9 +95,8 @@
USE_L10N = True
USE_TZ = True


ROOT_URLCONF = 'cleanerversion.urls'


STATIC_URL = '/static/'

VERSIONS_USE_UUIDFIELD = False
2 changes: 2 additions & 0 deletions cleanerversion/settings/pg_travis.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
'PORT': '5432',
},
}

VERSIONS_USE_UUIDFIELD = True
7 changes: 4 additions & 3 deletions cleanerversion/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.conf.urls import patterns, url
from django.conf.urls import url
from django.contrib import admin

urlpatterns = patterns('',
url(r'^admin/', admin.site.urls, ), )
urlpatterns = [
url(r'^admin/', admin.site.urls, ),
]
33 changes: 23 additions & 10 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
import cleanerversion

sys.path.insert(len(sys.path), os.path.abspath('..'))

# -- General configuration ------------------------------------------------
Expand Down Expand Up @@ -51,16 +53,17 @@

# General information about the project.
project = u'CleanerVersion'
copyright = u'2014, Jean-Christophe Zulian, Brian King, Andrea Marcacci, Manuel Jeckelmann'
copyright = u'2014, Jean-Christophe Zulian, Brian King, Andrea Marcacci, ' \
u'Manuel Jeckelmann'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '1.2'
version = cleanerversion.get_version(2)
# The full version, including alpha/beta/rc tags.
release = '1.2.2'
release = cleanerversion.get_version()

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down Expand Up @@ -204,7 +207,8 @@
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'CleanerVersion.tex', u'CleanerVersion Documentation',
u'Jean-Christophe Zulian, Brian King, Andrea Marcacci, Manuel Jeckelmann', 'manual'),
u'Jean-Christophe Zulian, Brian King, Andrea Marcacci, Manuel Jeckelmann',
'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
Expand Down Expand Up @@ -233,8 +237,12 @@
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'cleanerversion', u'CleanerVersion Documentation',
[u'Jean-Christophe Zulian, Brian King, Andrea Marcacci, Manuel Jeckelmann'], 1)
('index',
'cleanerversion',
u'CleanerVersion Documentation',
[u'Jean-Christophe Zulian, Brian King, Andrea Marcacci, '
u'Manuel Jeckelmann'],
1)
]

# If true, show URL addresses after external links.
Expand All @@ -247,9 +255,13 @@
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'CleanerVersion', u'CleanerVersion Documentation',
u'Jean-Christophe Zulian, Brian King, Andrea Marcacci, Manuel Jeckelmann', 'CleanerVersion',
'One line description of project.', 'Miscellaneous'),
('index',
'CleanerVersion',
u'CleanerVersion Documentation',
u'Jean-Christophe Zulian, Brian King, Andrea Marcacci, Manuel Jeckelmann',
'CleanerVersion',
'One line description of project.',
'Miscellaneous'),
]

# Documents to append as an appendix to all manuals.
Expand All @@ -268,5 +280,6 @@
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
'python': ('http://docs.python.org/', None),
'django': ('https://docs.djangoproject.com/en/dev/', 'https://docs.djangoproject.com/en/dev/_objects/')
'django': ('https://docs.djangoproject.com/en/dev/',
'https://docs.djangoproject.com/en/dev/_objects/')
}
47 changes: 30 additions & 17 deletions docs/doc/historization_with_cleanerversion.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Historization with CleanerVersion
*********************************

Disclaimer: This documentation as well as the CleanerVersion application code have been written to work against Django
1.8.x. The documentation may not be accurate anymore when using more recent versions of Django.
1.9.x through 1.11.x. The documentation may not be accurate anymore when using more recent versions of Django.

.. _cleanerversion-quick-starter:

Expand Down Expand Up @@ -56,8 +56,8 @@ would be a working example, if place in the same source file. Here's how::
phone = CharField(max_length=200)

Assuming you know how to deal with `Django Models <https://docs.djangoproject.com/en/stable/topics/db/models/>`_ (you
will need to sync your DB before your code gets usable; Or you're only testing, then that step is done by Django), the
next step is using your model to create some entries::
will need to migrate your DB before your code gets usable; Or you're only testing, then that step is done by Django),
the next step is using your model to create some entries::

p = Person.objects.create(name='Donald Fauntleroy Duck', address='Duckburg', phone='123456')
t1 = datetime.utcnow().replace(tzinfo=utc)
Expand Down Expand Up @@ -304,8 +304,8 @@ Here's an example with a sportsclub that can practice at most one sporty discipl
name = CharField(max_length=200)
rules = CharField(max_length=200)

If a M2O relationship can also be unset, don't forget to set the nullable flag (null=true) as an argument of the
``VersionedForeignKey`` field.
If a many-to-one (M2O) relationship can also be unset, don't forget to set the nullable flag (null=true) as an argument
of the ``VersionedForeignKey`` field.

Adding objects to a versioned M2O relationship
----------------------------------------------
Expand Down Expand Up @@ -544,8 +544,8 @@ The syntax for soft-deleting is the same as the standard Django Model deletion s

Notes about using prefetch_related
----------------------------------
`prefetch_related <https://docs.djangoproject.com/en/1.8/ref/models/querysets/#prefetch-related>`_ accepts
simple sting lookups or `Prefetch <https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.Prefetch>`_
`prefetch_related <https://docs.djangoproject.com/en/stable/ref/models/querysets/#prefetch-related>`_ accepts
simple sting lookups or `Prefetch <https://docs.djangoproject.com/en/stable/ref/models/querysets/#django.db.models.Prefetch>`_
objects.

When using ``prefetch_related`` with CleanerVersion, the generated query that fetches the related objects will
Expand Down Expand Up @@ -603,6 +603,7 @@ If you have an object item1, and know that it existed at some other time t1, you

Accessing the current version of an object
------------------------------------------

``current_version(obj)`` will return the latest version of the obj, or ``None`` if no version is currently active.

Note that if the current object thinks that it is the current object (e.g. ``version_end_date`` is ``None``),
Expand Down Expand Up @@ -651,10 +652,12 @@ reverse foreign key, one-to-one or many-to-many fields). Valid values for ``rel

Deleting objects
================

You can expect ``delete()`` to behave like you are accustomed to in Django, with these differences:

Not actually deleted from the database
--------------------------------------

When you call ``delete()`` on a versioned object, it is not actually removed from the database. Instead, it's
``version_end_date`` is changed from None to a timestamp.

Expand All @@ -663,6 +666,7 @@ they are terminated by setting a ``version_end_date``.

on_delete handlers
------------------

`on_delete handlers <https://docs.djangoproject.com/en/stable/ref/models/fields/#django.db.models.ForeignKey.on_delete>`_
behave like this:

Expand Down Expand Up @@ -779,15 +783,17 @@ will need to be ready to handle that.
Postgresql specific
===================

Django creates `extra indexes <https://docs.djangoproject.com/en/1.8/ref/databases/#indexes-for-varchar-and-text-columns>`_
for CharFields that are used for like queries (e.g. WHERE foo like 'fish%'). Since Django 1.6 (the version CleanerVersion originally
targeted) did not have native database UUID fields, the UUID fields that are used for the id and identity columns of Versionable models
have these extra indexes created. In fact, these fields will never be compared using the like operator. Leaving these indexes would create a
performance penalty for inserts and updates, especially for larger tables. ``versions.util.postgresql`` has a function
``remove_uuid_id_like_indexes`` that can be used to remove these extra indexes.
Django creates `extra indexes <https://docs.djangoproject.com/en/stable/ref/databases/#indexes-for-varchar-and-text-columns>`_
for CharFields that are used for like queries (e.g. WHERE foo like 'fish%'). Since Django 1.6 (the version
CleanerVersion originally targeted) did not have native database UUID fields, the UUID fields that are used for the id
and identity columns of Versionable models have these extra indexes created. In fact, these fields will never be
compared using the like operator. Leaving these indexes would create a performance penalty for inserts and updates,
especially for larger tables. ``versions.util.postgresql`` has a function ``remove_uuid_id_like_indexes`` that can be
used to remove these extra indexes.

For the issue of `Unique Indexes`_, ``versions.util.postgresql`` has a function ``create_current_version_unique_indexes`` that can
be used to create unique indexes. For this to work, it's necessary to define a VERSION_UNIQUE attribute when defining the model::
For the issue of `Unique Indexes`_, ``versions.util.postgresql`` has a function
``create_current_version_unique_indexes`` that can be used to create unique indexes. For this to work, it's necessary
to define a VERSION_UNIQUE attribute when defining the model::

class Person(Versionable):
name = models.CharField(max_length=40)
Expand Down Expand Up @@ -847,6 +853,13 @@ object is current.

Upgrade notes
=============

CleanerVersion 2.x / Django 1.9/1.10/1.11
-------------------------------------------

In Django 1.9 major changes to the ORM layer have been introduced, which made existing versions of CleanerVersion for
incompatible with Django 1.9 onwards. We decided to release a separate major version to support the Django 1.9 to 1.11.

CleanerVersion 1.6.0 / Django 1.8.3
-----------------------------------
Starting with CleanerVersion 1.6.0, Django's ``UUIDField`` will be used for the ``id``, ``identity``,
Expand Down Expand Up @@ -876,8 +889,8 @@ You must choose one or the other solution; not doing so will result in your appl
Known Issues
============

* No `multi-table inheritance <https://docs.djangoproject.com/en/stable/topics/db/models/#multi-table-inheritance>`_ support.
Multi-table inheritance currently does not work if the parent model has a Versionable base class.
* No `multi-table inheritance <https://docs.djangoproject.com/en/stable/topics/db/models/#multi-table-inheritance>`_
support. Multi-table inheritance currently does not work if the parent model has a Versionable base class.
See `this issue <https://github.com/swisscom/cleanerversion/issues/19>`_ for more details.

* Creating `Unique Indexes`_ is a bit tricky for versioned database tables. A solution is provided for Postgresql (see the
Expand Down
Empty file modified manage.py
100644 → 100755
Empty file.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Django>=1.10
Loading

0 comments on commit 73bf78e

Please sign in to comment.