Skip to content

Commit

Permalink
Release version 2.0.0 beta
Browse files Browse the repository at this point in the history
  • Loading branch information
spectras committed Nov 20, 2018
1 parent c067021 commit da1cbe8
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 45 deletions.
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ Releases
Django-hvad uses the same release pattern as Django. The following versions
are thus available:

* Stable branch 1.7, available through `PyPI`_ and git branch ``releases/1.7.x``.
* Stable branch 1.8, available through `PyPI`_ and git branch ``releases/1.8.x``.
* Development branch 1.9, available through git branch ``master``.
* Legacy branch 1.8, available through `PyPI`_ and git branch ``releases/1.8.x``.
* Stable branch 2.0, available through `PyPI`_ and git branch ``releases/2.0.x``.
* Development branch 2.1, available through git branch ``master``.

Stable branches have minor bugfix releases as needed, with guaranteed compatibility.
See the `installation guide`_ for details, or have a look at the `release notes`_.
Expand Down
5 changes: 2 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
'github'
]
intersphinx_mapping = {
'python': ('http://docs.python.org/2.7', None),
'python': ('http://docs.python.org/3.6', None),
'django': ('http://readthedocs.org/docs/django/en/latest/', None),
}

Expand All @@ -42,7 +42,7 @@

# General information about the project.
project = u'django-hvad'
copyright = u'2011-2016, Kristian Øllegaard, Jonas Obrist & contributors'
copyright = u'2011-2018, Kristian Øllegaard, Jonas Obrist & contributors'

version = '2.0'
release = '2.0.0'
Expand All @@ -64,7 +64,6 @@
html_style = 'stylesheet.css'
html_static_path = ['_static']

html_use_smartypants = True
html_show_sourcelink = False

# Custom sidebar templates, maps document names to template names.
Expand Down
9 changes: 6 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ new versions will usually be introduced when they reach the beta stage.

Thus, django-hvad 2.0 is tested on the following configurations:

- Django 1.8.15, running Python 2.7, 3.4 or 3.5.
- Django 1.9.10, running Python 2.7, 3.4 or 3.5.
- Django 1.10.2, running Python 2.7, 3.4 or 3.5.
- Django 2.1.2, running Python 3.5 or 3.6.

As django-hvad 2.0 is incompatible with older releases, django-hvad 1.8.0 is still
supported with:

- Django 1.11, running Python 2.7, 3.4 or 3.5.

All tests are run against MySQL and PostgreSQL.

Expand Down
84 changes: 58 additions & 26 deletions docs/internal/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,11 @@
A special value used with :meth:`~hvad.models.TranslatableModel.__init__`
to prevent automatic creation of a translation.

.. function:: create_translations_model(model, related_name, meta, **fields)

A model factory used to create the :term:`Translations Model`. Makes sure
that the *unique_together* option on the options (meta) contain
``('language_code', 'master')`` as they always have to be unique together.
Sets the ``master`` foreign key to *model* onto the
:term:`Translations Model` as well as the ``language_code`` field, which is
a database indexed char field with a maximum of 15 characters.

Returns the new model.

.. function:: contribute_translations(cls, rel)

Gets called from :func:`prepare_translatable_model` to set the
descriptors of the fields on the :term:`Translations Model` onto the
model.

.. function:: prepare_translatable_model(sender)

Gets called from :class:`~django.db.models.Model`'s metaclass to
customize model creation. Performs checks, then contributes translations
and translation manager onto models that inherit
Gets called from :class:`~django.db.models.Model` after Django has
completed its setup. It customizes model creation for translations.
Most notably, it performs checks, overrides ``_meta`` methods and defines
translation-aware manager on models that inherit
:class:`~hvad.models.TranslatableModel`.

****************
Expand All @@ -41,15 +24,64 @@ TranslatedFields

A wrapper for the translated fields which is set onto
:class:`TranslatableModel` subclasses to define what fields are translated.

Internally this is just used because Django calls the
:meth:`contribute_to_class` method on all attributes of a model, if such a
method is available.

.. method:: contribute_to_class(self, cls, name)

Calls :func:`create_translations_model`.
Invoked by Django while setting up a model that defines translated fields.
Django passes is the model being built as ``cls`` and the field name
used for translated fields as ``name``.

It triggers translations model creation from the list of field the
``TranslatedFields`` object was created with, and glues the shared
model and the translations model together.

.. method:: create_translations_model(self, model, related_name)

A model factory used to create the :term:`Translations Model` for the
given shared ``model``. The translations model will include:

* A foreign key back to the shared model, named ``master``, with the
given ``related_name``.
* A ``language_code`` field, indexed together with ``master``, for
looking up a shared model instance's translations.
* All fields passed to ``TranslatedFields`` object.

Adds the new model to the shared model's module and returns it.

.. method:: contribute_translations(self, model, translations_model, related_name)

Glues the shared ``model`` and the ``translations_model`` together.
This step includes setting up attribute descriptors for all translatable
fields onto the shared ``model``.

.. method:: _scan_model_bases(self, model)

Recursively walks all ``model``'s base classes, looking for translation
models and collecting translatable fields. Used to build the inheritance
tree of a :term:`Translations Model`.

Returns the list of bases and the list of fields.

.. method:: _build_meta_class(self, model, tfields)

Creates the :djterm:`Meta <meta-options>` class for the
:term:`Translations Model` passed as ``model``. Takes ``tfields`` as a
list of all fields names referring to translatable fields.

Returns the created meta class.

.. staticmethod:: _split_together(constraints, fields, name)

Helper method that partitions constraint tuples into shared-model
constraints and translations model constraints. Argument ``constraints``
is an iterable of contrain tuples, ``fields`` is the list of translated
field names and ``name`` is the name of the option being handled (used
for raising exceptions).

Returns two list of constraints. First for shared model, second for
translations model. Raises an
:exc:`~django.core.exceptions.ImproperlyConfigured` exception if a
constraint has both translated and untranslated fields.

********************
BaseTranslationModel
Expand Down
34 changes: 30 additions & 4 deletions docs/public/migrate.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ In addition, some settings have changed and must be updated:
backwards-compatible loading of translations. In hvad2, by default,
accessing a translated field when no translation is loaded no longer
causes an automatic attempt to load one. This setting enables
that behavior again, for compatibility with code relying on that
behavior.
that behavior again, for compatibility with code relying on it.

Please note this is intended as a compatibility setting, which will be removed
in the future.

Models
======
Expand All @@ -48,11 +50,11 @@ code samples will assume you named it ``translations``.
The new features should simplify your code a lot when it comes to
manually handling translations and leveraging Django caching and
prefetching while working on multilingual models. Some incompatible changes
also had to be performed, and existing code must be updating in the following way:
also had to be performed, and existing code must be updated in the following way:

.. class:: TranslatableModel(*args, **kwargs)

Invoking a translatable model constructor now always instanciates and
Invoking a translatable model constructor now always instantiates and
activates a translation. If a ``language_code`` argument is passed,
the translation will be in that language, otherwise it will be in
:func:`current language <django.utils.translation.get_language>`.
Expand Down Expand Up @@ -126,3 +128,27 @@ also had to be performed, and existing code must be updating in the following wa
# BECOMES
instance.translate('en')
instance.do_something()

Queries
=======

Due to some limitations on the way queries are combined in Django ORM, one muse be careful
when filtering on translated fields. Two separate ``filter()`` calls will result on
filtering separately. Under the hood, translated fields are accessed through a ``JOIN``
query, and each ``filter()`` call has its own context. That is::

# Query 1
MyModel.objects.language('all').filter(foo='baz', bar=42)

# Query 2
MyModel.objects.language('all').filter(foo='baz').filter(bar=42)

Assuming both ``foo`` and ``bar`` are translated fields, then:

* Query #1 returns objects that have a language in which **both** ``foo`` and ``bar`` match.
* Query #2 returns objects that have a language in which **either** ``foo`` or ``bar`` matches.

This is similar to how Django behaves with joins (because this is how the query is handled).
Queries that work on a single language are not affected, though depending on the database engine
the double-join of query #2 might degrade performance.

27 changes: 26 additions & 1 deletion docs/public/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,32 @@ Release Notes
#############

*****************************
1.8.0 - current release
2.0.0 beta - current release
*****************************

Released on November 20, 2018

Python and Django versions supported:

- Django 2.1 and newer.
- Python 3.5 and newer.
- Older versions are **not** supported. Please stick to 1.8.0 for older versions.

This is a major release with breaking changes. Please see the
:ref:`migration guide <migrate-hvad-1>`.

Major changes:

- Query engine was refactored to use a parameterized `JOIN` clause.
- Translation caching now works with Django API.
- Automatic loading has been removed, in favor of upfront caching of translations.
- Introspection API was reworked (see the new :ref:`translations <model-translations>` accessor).

As many changes have been introduced, this release might introduce more bugs than usual, which
is why it is flagged as `beta`.

*****************************
1.8.0
*****************************

Released on April 28, 2017
Expand Down
8 changes: 3 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from setuptools import setup, find_packages
import hvad

with open('README.rst', 'rb') as f:
long_description = f.read().decode('utf-8')
with open('README.rst', 'r') as fd:
long_description = fd.read()

setup(
name = 'django-hvad',
Expand All @@ -22,16 +22,14 @@
zip_safe=False,
include_package_data = True,
install_requires=[
'Django>=1.8',
'Django>=2.1',
],
classifiers = [
"Development Status :: 5 - Production/Stable",
"Framework :: Django",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Topic :: Database",
Expand Down

0 comments on commit da1cbe8

Please sign in to comment.