Skip to content

Commit da1cbe8

Browse files
committed
Release version 2.0.0 beta
1 parent c067021 commit da1cbe8

File tree

7 files changed

+128
-45
lines changed

7 files changed

+128
-45
lines changed

README.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ Releases
113113
Django-hvad uses the same release pattern as Django. The following versions
114114
are thus available:
115115

116-
* Stable branch 1.7, available through `PyPI`_ and git branch ``releases/1.7.x``.
117-
* Stable branch 1.8, available through `PyPI`_ and git branch ``releases/1.8.x``.
118-
* Development branch 1.9, available through git branch ``master``.
116+
* Legacy branch 1.8, available through `PyPI`_ and git branch ``releases/1.8.x``.
117+
* Stable branch 2.0, available through `PyPI`_ and git branch ``releases/2.0.x``.
118+
* Development branch 2.1, available through git branch ``master``.
119119

120120
Stable branches have minor bugfix releases as needed, with guaranteed compatibility.
121121
See the `installation guide`_ for details, or have a look at the `release notes`_.

docs/conf.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
'github'
3232
]
3333
intersphinx_mapping = {
34-
'python': ('http://docs.python.org/2.7', None),
34+
'python': ('http://docs.python.org/3.6', None),
3535
'django': ('http://readthedocs.org/docs/django/en/latest/', None),
3636
}
3737

@@ -42,7 +42,7 @@
4242

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

4747
version = '2.0'
4848
release = '2.0.0'
@@ -64,7 +64,6 @@
6464
html_style = 'stylesheet.css'
6565
html_static_path = ['_static']
6666

67-
html_use_smartypants = True
6867
html_show_sourcelink = False
6968

7069
# Custom sidebar templates, maps document names to template names.

docs/index.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ new versions will usually be introduced when they reach the beta stage.
2222

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

25-
- Django 1.8.15, running Python 2.7, 3.4 or 3.5.
26-
- Django 1.9.10, running Python 2.7, 3.4 or 3.5.
27-
- Django 1.10.2, running Python 2.7, 3.4 or 3.5.
25+
- Django 2.1.2, running Python 3.5 or 3.6.
26+
27+
As django-hvad 2.0 is incompatible with older releases, django-hvad 1.8.0 is still
28+
supported with:
29+
30+
- Django 1.11, running Python 2.7, 3.4 or 3.5.
2831

2932
All tests are run against MySQL and PostgreSQL.
3033

docs/internal/models.rst

Lines changed: 58 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,11 @@
99
A special value used with :meth:`~hvad.models.TranslatableModel.__init__`
1010
to prevent automatic creation of a translation.
1111

12-
.. function:: create_translations_model(model, related_name, meta, **fields)
13-
14-
A model factory used to create the :term:`Translations Model`. Makes sure
15-
that the *unique_together* option on the options (meta) contain
16-
``('language_code', 'master')`` as they always have to be unique together.
17-
Sets the ``master`` foreign key to *model* onto the
18-
:term:`Translations Model` as well as the ``language_code`` field, which is
19-
a database indexed char field with a maximum of 15 characters.
20-
21-
Returns the new model.
22-
23-
.. function:: contribute_translations(cls, rel)
24-
25-
Gets called from :func:`prepare_translatable_model` to set the
26-
descriptors of the fields on the :term:`Translations Model` onto the
27-
model.
28-
2912
.. function:: prepare_translatable_model(sender)
30-
31-
Gets called from :class:`~django.db.models.Model`'s metaclass to
32-
customize model creation. Performs checks, then contributes translations
33-
and translation manager onto models that inherit
13+
Gets called from :class:`~django.db.models.Model` after Django has
14+
completed its setup. It customizes model creation for translations.
15+
Most notably, it performs checks, overrides ``_meta`` methods and defines
16+
translation-aware manager on models that inherit
3417
:class:`~hvad.models.TranslatableModel`.
3518

3619
****************
@@ -41,15 +24,64 @@ TranslatedFields
4124

4225
A wrapper for the translated fields which is set onto
4326
:class:`TranslatableModel` subclasses to define what fields are translated.
44-
45-
Internally this is just used because Django calls the
46-
:meth:`contribute_to_class` method on all attributes of a model, if such a
47-
method is available.
4827

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

51-
Calls :func:`create_translations_model`.
30+
Invoked by Django while setting up a model that defines translated fields.
31+
Django passes is the model being built as ``cls`` and the field name
32+
used for translated fields as ``name``.
33+
34+
It triggers translations model creation from the list of field the
35+
``TranslatedFields`` object was created with, and glues the shared
36+
model and the translations model together.
37+
38+
.. method:: create_translations_model(self, model, related_name)
39+
40+
A model factory used to create the :term:`Translations Model` for the
41+
given shared ``model``. The translations model will include:
42+
43+
* A foreign key back to the shared model, named ``master``, with the
44+
given ``related_name``.
45+
* A ``language_code`` field, indexed together with ``master``, for
46+
looking up a shared model instance's translations.
47+
* All fields passed to ``TranslatedFields`` object.
48+
49+
Adds the new model to the shared model's module and returns it.
50+
51+
.. method:: contribute_translations(self, model, translations_model, related_name)
52+
53+
Glues the shared ``model`` and the ``translations_model`` together.
54+
This step includes setting up attribute descriptors for all translatable
55+
fields onto the shared ``model``.
56+
57+
.. method:: _scan_model_bases(self, model)
58+
59+
Recursively walks all ``model``'s base classes, looking for translation
60+
models and collecting translatable fields. Used to build the inheritance
61+
tree of a :term:`Translations Model`.
62+
63+
Returns the list of bases and the list of fields.
64+
65+
.. method:: _build_meta_class(self, model, tfields)
66+
67+
Creates the :djterm:`Meta <meta-options>` class for the
68+
:term:`Translations Model` passed as ``model``. Takes ``tfields`` as a
69+
list of all fields names referring to translatable fields.
70+
71+
Returns the created meta class.
72+
73+
.. staticmethod:: _split_together(constraints, fields, name)
74+
75+
Helper method that partitions constraint tuples into shared-model
76+
constraints and translations model constraints. Argument ``constraints``
77+
is an iterable of contrain tuples, ``fields`` is the list of translated
78+
field names and ``name`` is the name of the option being handled (used
79+
for raising exceptions).
5280

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

5486
********************
5587
BaseTranslationModel

docs/public/migrate.rst

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ In addition, some settings have changed and must be updated:
3434
backwards-compatible loading of translations. In hvad2, by default,
3535
accessing a translated field when no translation is loaded no longer
3636
causes an automatic attempt to load one. This setting enables
37-
that behavior again, for compatibility with code relying on that
38-
behavior.
37+
that behavior again, for compatibility with code relying on it.
38+
39+
Please note this is intended as a compatibility setting, which will be removed
40+
in the future.
3941

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

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

55-
Invoking a translatable model constructor now always instanciates and
57+
Invoking a translatable model constructor now always instantiates and
5658
activates a translation. If a ``language_code`` argument is passed,
5759
the translation will be in that language, otherwise it will be in
5860
:func:`current language <django.utils.translation.get_language>`.
@@ -126,3 +128,27 @@ also had to be performed, and existing code must be updating in the following wa
126128
# BECOMES
127129
instance.translate('en')
128130
instance.do_something()
131+
132+
Queries
133+
=======
134+
135+
Due to some limitations on the way queries are combined in Django ORM, one muse be careful
136+
when filtering on translated fields. Two separate ``filter()`` calls will result on
137+
filtering separately. Under the hood, translated fields are accessed through a ``JOIN``
138+
query, and each ``filter()`` call has its own context. That is::
139+
140+
# Query 1
141+
MyModel.objects.language('all').filter(foo='baz', bar=42)
142+
143+
# Query 2
144+
MyModel.objects.language('all').filter(foo='baz').filter(bar=42)
145+
146+
Assuming both ``foo`` and ``bar`` are translated fields, then:
147+
148+
* Query #1 returns objects that have a language in which **both** ``foo`` and ``bar`` match.
149+
* Query #2 returns objects that have a language in which **either** ``foo`` or ``bar`` matches.
150+
151+
This is similar to how Django behaves with joins (because this is how the query is handled).
152+
Queries that work on a single language are not affected, though depending on the database engine
153+
the double-join of query #2 might degrade performance.
154+

docs/public/release_notes.rst

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,32 @@ Release Notes
33
#############
44

55
*****************************
6-
1.8.0 - current release
6+
2.0.0 beta - current release
7+
*****************************
8+
9+
Released on November 20, 2018
10+
11+
Python and Django versions supported:
12+
13+
- Django 2.1 and newer.
14+
- Python 3.5 and newer.
15+
- Older versions are **not** supported. Please stick to 1.8.0 for older versions.
16+
17+
This is a major release with breaking changes. Please see the
18+
:ref:`migration guide <migrate-hvad-1>`.
19+
20+
Major changes:
21+
22+
- Query engine was refactored to use a parameterized `JOIN` clause.
23+
- Translation caching now works with Django API.
24+
- Automatic loading has been removed, in favor of upfront caching of translations.
25+
- Introspection API was reworked (see the new :ref:`translations <model-translations>` accessor).
26+
27+
As many changes have been introduced, this release might introduce more bugs than usual, which
28+
is why it is flagged as `beta`.
29+
30+
*****************************
31+
1.8.0
732
*****************************
833

934
Released on April 28, 2017

setup.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from setuptools import setup, find_packages
22
import hvad
33

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

77
setup(
88
name = 'django-hvad',
@@ -22,16 +22,14 @@
2222
zip_safe=False,
2323
include_package_data = True,
2424
install_requires=[
25-
'Django>=1.8',
25+
'Django>=2.1',
2626
],
2727
classifiers = [
2828
"Development Status :: 5 - Production/Stable",
2929
"Framework :: Django",
3030
"Intended Audience :: Developers",
3131
"License :: OSI Approved :: BSD License",
3232
"Operating System :: OS Independent",
33-
"Programming Language :: Python :: 2.7",
34-
"Programming Language :: Python :: 3.4",
3533
"Programming Language :: Python :: 3.5",
3634
"Programming Language :: Python :: 3.6",
3735
"Topic :: Database",

0 commit comments

Comments
 (0)