9. Release Notes¶
9.1. 1.8.0 - current release¶
Released on April 28, 2017
Python and Django versions supported:
- Support for Django 1.10 was added.
- Django 1.7 is no longer supported.
- So, as a reminder, supported Django versions for this release are: 1.8 LTS, 1.9, 1.10.x (for x ≥ 1) and 1.11.
New features:
- Automatic loading of translations on attribute access can now be disabled,
by setting
HVAD["AUTOLOAD_TRANSLATIONS"]
toFalse
. This will prevent hvad from initiating database queries. Accessing translatable attributes with no translation loaded will then raise anAttributeError
. - It is possible to automatically install
TranslationQueryset
as the default queryset for all translatable models, by settingHVAD["USE_DEFAULT_QUERYSET"]
toTrue
. Specifically, it changesdefault_class
to be aTranslationQueryset
instead of aQuerySet
. See the section about overriding the default queryset for advantages and caveats of doing so. - Field declaration for internal
language_code
attribute can be overriden. — #332.
Compatibility warnings:
All settings have been moved to a unique
HVAD
dictionary. Please update your django settings accordingly.Deprecated class
FallbackQueryset
has been removed. Using it along withFallbackQueryset.use_fallbacks()
did not work on Django 1.9 and newer and was deprecated on older versions. Using it without that method made it behave like a regular queryset. So as a summary,- Code using .untranslated().use_fallbacks() must be replaced with .language().fallbacks().
- All other uses of FallbackQueryset can be safely replaced with a regular
QuerySet
.
Translated admin no longer shows objects lacking a translation. This was already the case on Django 1.9 and newer, and this behavior now extends to all Django versions. Such objects should not happen anyway, and throw a warning when encountered.
Fixes:
- Increase speed of translated attribute access by ~30%, by avoiding a method call when a translation is loaded.
- Attempting to use a reserved name for a translated field now raises an
ImproperlyConfigured
exception instead of silently ignoring the field. - Instances created by serializers using
TranslatableModelMixin
in normal, non-enforcing mode can no longer be created without a translation. — #322.
9.2. 1.7.0¶
Released on February 8, 2017
New features:
- Support for
defer()
andonly()
was added. Note that deferring all translated fields will not result in translation being skipped, because 1) it needs to be inspected for language resolution and 2) loaded translation language must be fixed at query time. Support is limited to immediate fields at the moment, ie it is not possible to defer fields of additionals models loaded throughselect_related()
.
Compatibility warnings:
- Internal admin method
TranslatableAdmin.get_available_languages()
is deprecated and will be removed. UseTranslatableModel.get_available_languages()
instead. - Internal admin method
TranslatableAdmin.get_language_tabs()
signature changed.
Fixes:
- Do not consider annotations when looking up translatable query fields. Fixes errors that could arise when using some annotation names. — #303.
- Accept special value
__all__
for form field list, as a synonym forNone
, meaning include all known fields. — #313. - Fix translation deletion links that were improperly generated when using inline change forms. — #317.
9.3. 1.6.0¶
Released on September 6, 2016
Python and Django versions supported:
- Support for Django 1.10 was added. It requires version 1.10.1 or better.
- So, as a reminder, supported Django versions for this release are: 1.7, 1.8 LTS, 1.9, 1.10.x (for x ≥ 1).
Fixes:
- No longer set
master
toNULL
before clearing translations when usingdelete_translations()
. This only triggers one query instead of two, and allows enforcing non-null foreign key at the database level. - Django system checks are now run in the test suite in addition to hvad’s tests.
9.4. 1.5.1¶
Released on May 23, 2016
Fixes:
- Filter out m2m and generic fields in
update_translation()
so it does not bite when using (unsupported) m2m fields or generic relations in a translation — #285.
9.5. 1.5.0¶
Released on February 2, 2016
Python and Django versions supported:
- Django 1.4 LTS is no longer supported.
- So, as a reminder, supported Django versions for this release are: 1.7, 1.8 LTS, 1.9.
New features:
- It is now possible to specify a custom translation base
model, allowing advanced translation manipulation, such as controlling their loading
with
from_db()
. - Translated model’s
save()
method now accepts translated field names inupdate_fields
. Also, if only translated fields, or only untranslated fields are specified inupdate_fields
, the extra query will be skipped. - Support for third parameter on
ModelAdmin
‘sget_object()
method was added. - Experimental support for using language(‘all’) together with
select_related()
is being introduced. Please check the generated queries if you use it. Feedback is appreciated.
Compatibility Warnings:
- Saving of translations now happens in the model’s
save()
method. It used to happen in thepost_save
signal. TranslationsMixin
now splits the update intoupdate
andupdate_translation
methods. The former is called once per save, and uses the latter as many times as required to update all translations.
Fixes:
- Translation deletion URIs are no longer broken on Django 1.9 — #279.
- REST framework translation support now uses
update_fields
to reduce the number of queries when updating an object. - REST framework translation support no longer breaks when using
PrimaryKeyRelatedField
andTranslationsMixin
together — #278. - Admin no longer uses deprecated
patterns
function — #268.
9.6. 1.4.0¶
Released on November 10, 2015
Python and Django versions supported:
- Support for Python 3.5 was added.
- Support for Django 1.9 was added.
- Django 1.6 is no longer officially supported.
- Django 1.4 LTS has reached its end of life, and support will be dropped in hvad 1.5.
- So, as a reminder, supported versions for this release are: 1.4 LTS, 1.7, 1.8 LTS, 1.9.
Compatibility Warnings:
- As a result of the annotations fix (see below), applications that worked around
annotate()
‘s shortcomings on translation querysets are likely to break, asannotate()
has been fixed. The workarounds should be simply removed. - Method
FallbackQueryset.use_fallbacks()
is not supported on Django 1.9 and newer (and deprecated on other versions, see below). Please use TranslationQueryset.fallbacks() instead. - Translated admin no longer shows objects lacking a translation, starting from Django 1.9. This behavior will be extended to all Django versions in the next release. Such objects should not happen anyway, and throw a warning when encountered.
- Translation model building has been refactored. It is functionally equivalent to its previous implementation (it passes the exact same test suite), but code depending on the internals and inner implementation details could break.
Deprecation List:
Method
FallbackQueryset.use_fallbacks()
is now deprecated on Django 1.6 and newer. The plan is to completely dropFallbackQueryset
in the near future, and letTranslationManager.untranslated()
default to returning a plain Django queryset, thus enablingMyModel.objects.untranslated()
to give access to all features a plain Django queryset supports.For queries that need fallbacks, the
use_fallbacks()
method has long been superseded by TranslationQueryset.fallbacks(), which is better tested, uses simpler code yet supports more features. Please update your queries accordingly.MyModel.objects.untranslated().use_fallbacks('en', 'ja', 'fr')
should be rewritten asMyModel.objects.language('en').fallbacks('ja', 'fr')
, or evenMyModel.objects.language().fallbacks()
to have the query use your application’s language settings automatically.
Fixes:
- Annotations added to a
TranslationQueryset
using theannotate()
method no longer end up on the translation cache with amaster__
prefix. - Specifying translation fields in
unique_together
on translatable models no longer causes Django to generate incorrect migrations. — #260. - When no
Meta
options are set on a TranslatableModelForm, the auto-created one now correctly inherits that of its first base class that has one set — #262. - Using
language('all')
together withvalues()
no longer breaks — #264.
9.7. 1.3.0¶
Released on July 29, 2015
This release is a collection of fixes and improvements, some of which may introduce minor compatibility issues. Please make sure you fix any deprecation warnings before upgrading to avoid those issues.
Python and Django versions supported:
- Django 1.5 is no longer officially supported.
- Django 1.6 has reached its end of life, and support will be dropped in hvad 1.4.
- As a reminder, Django 1.4 is still supported, so supported versions for this release are: 1.4, 1.6, 1.7, 1.8.
New Features:
- Russian and Latvian translations are now included, thanks to Juris Malinens — #248.
Compatibility Warnings: deprecated features pending removal in 1.3 have been removed. Most notably:
- Calling
save()
on an invalid form now raises an assertion exception. - Classes
TranslatableModelBase
,TranslationFallbackManager
,TranslatableBaseView
and methodTranslationManager.using_translations()
no longer exist. - Deprecated view methods and context modifiers now raise an assertion exception.
Fixes:
- Lift Django restrictions on translated fields in
Meta.unique_together
andMeta.index_together
— #252. - Properly forward model validation methods to translation validation methods, so that model validation detects constraint violations on the translation as well. Fixes duplicate detection in admin for unique constraints on translations — #251.
- Detect name clash between translated and non-translated fields — #240.
- Validate that at least one translation is provided when deserializing objects in
TranslationsMixin
— #256. - Fix handling of model edition from an admin popup in Django 1.7 and newer — #253.
- Generate proper ORM structures for fallbacks. Avoids table relabeling breaking
queries, for instance when using
update()
or feeding a queryset to another queryset — #250.
9.8. 1.2.2¶
Released on June 3, 2015
Fixes:
- Properly handle
language_code
inMeta.unique_together
andMeta.index_together
— #244.
9.9. 1.2.1¶
Released on April 29, 2015
Fixes:
- Make passing the
model
argument to queryset’s__init__
optional. Still allow it to be passed either as a positional or named argument — #241.
9.10. 1.2.0¶
Released on March 19, 2015
This is a feature release, to push REST framework support onto the main package.
Python and Django versions supported:
- Due to this version being released early, end of support for Django 1.5 has been postponed until next release.
New features:
- Support for Django REST framework is now included. It requires REST framework version 3.1 or newer — #220.
9.12. 1.1.0¶
Released on February 17, 2015
Python and Django versions supported:
- hvad now supports Django 1.8.
- Django 1.5 has reached its end of life, and support will be dropped in hvad 1.2. Note however that Django 1.4 will still be supported.
New features:
- It is now possible to use translated fields in the
unique_together
andindex_together
settings on TranslatableModel. They cannot be mixed in a single constraint though, as table-spanning indexes are not supported by SQL databases. - The
annotate()
method is now supported. Support is still basic for now: annotations may not access more than one level of relation.
Compatibility warnings:
- Internal module
hvad.fieldtranslator
was no longer used, and was incompatible with Django 1.8. It has been removed. - Deprecated
using_translations()
has been removed. It can be safely replaced bylanguage()
. - Deprecated
TranslationFallbackManager
has been removed. Please use manager’suntranslated()
method instead. - Deprecated
TranslatableModelBase
metaclass has been removed. Since release 0.5, hvad does not trigger metaclass conflicts anymore – #188. - Overriding the language in
QuerySet.get()
andQuerySet.filter()
was deprecated in release 0.5, and has now been removed. Either use thelanguage()
method to set the correct language, or specifylanguage('all')
to filter manually throughget
andfilter
– #182. TranslatableModel
‘s Internal attribute_shared_field_names
has been removed.
Deprecation list:
- Passing
unique_together
orindex_together
as ameta
option onTranslatedFields
is now deprecated and will be unsupported in release 1.3. Put them in the model’sMeta
instead, alongside normal fields. - Calling
save()
on an invalid TranslatableModelForm is a bad practice and breaks on regular Django forms. This is now deprecated, and relevant checks will be removed in release 1.3. Please check the form is valid before saving it. - Generic views in
hvad.views
have been refactored to follow Django generic view behaviors. As a result, several non-standard methods are now deprecated. Please replace them with their Django equivalents — check #225.
9.13. 1.0.0¶
Released on December 19, 2014
Python and Django versions supported:
- Django 1.3 is no longer supported.
- Python 2.6 is no longer supported. Though it is likely to work for the time being, it has been dropped from the tested setups.
New features:
- TranslatableModelForm has been refactored to make its behavior more consistent. As a result, it exposes two distinct language selection modes, normal and enforce, and has a clear API for manually overriding the language — #221.
- The new features of
modelform_factory()
introduced by Django 1.6 and 1.7 are now available on translatable_modelform_factory as well — #221. - TranslationQueryset now has a fallbacks() method when running on Django 1.6 or newer, allowing the queryset to use fallback languages while retaining all its normal functionalities – #184.
- Passing additional
select
items in methodextra()
is now supported. — #207. - It is now possible to use TranslationQueryset as default queryset for translatable models. — #207.
- A lot of tests have been added, hvad now has 100% coverage on its core modules. Miscellaneous glitches found in this process were fixed.
- Added MySQL to tested database backends on Python 2.7.
Compatibility warnings:
- TranslatableModelForm has been refactored to make
its behavior more consistent. The core API has not changed, but edge cases are
now clearly specified and some inconsistencies have disappeared, which could
create issues, especially:
- Direct use of the form class, without passing through the factory method. This used to have an unspecified behavior regarding language selection. Behavior is now well-defined. Please ensure it works the way you expect it to.
Fixes:
- TranslatableModelForm‘s
clean()
can now return None as per the new semantics introduced in Django 1.7. — #217. - Using
Q object
logical combinations orexclude()
on a translation-aware manager returned byget_translation_aware_manager()
no longer yields wrong results. - Method
get_or_create()
now properly deals with Django 1.6-style transactions.
9.16. 0.5.0¶
Released on September 11, 2014
New features:
- New translationformset_factory and its companion
BaseTranslationFormSet
allow building a formset to work on an instance’s translations. Please have at look at its detailed documentation – #157. - Method
language()
now accepts the special value'all'
, allowing the query to consider all translations – #181. - Django 1.6+’s new
datetimes()
method is now available onTranslationQueryset
too – #175. - Django 1.6+’s new
earliest()
method is now available onTranslationQueryset
. - Calls to
language()
, passingNone
to use the current language now defers language resolution until the query is evaluated. It can now be used in form definitions directly, for instance for passing a custom queryset toModelChoiceField
– #171. - Similarly,
use_fallbacks()
can now be passedNone
as one of the fallbacks, and it will be replaced with current language at query evaluation time. - All queryset classes used by
TranslationManager
can now be customized thanks to the newfallback_class
anddefault_class
attributes. - Abstract models are now supported. The concrete class must still declare a
TranslatedFields
instance, but it can be empty – #180. - Django-hvad messages are now available in Italian – #178.
- The
Meta.ordering
model setting is now supported on translatable models. It accepts both translated and shared fields – #185, #12. - The
select_related()
method is no longer limited to 1 level depth – #192. - The
select_related()
method semantics is now consistent with that of regular querysets. It supports passingNone
to clear the list and mutiple calls mimic Django behavior. That is: cumulative starting from Django 1.7 and substitutive before – #192.
Deprecation list:
- The deprecated
nani
module was removed. - Method
using_translations()
is now deprecated. It can be safely replaced bylanguage()
with no arguments. - Setting
NANI_TABLE_NAME_SEPARATOR
was renamed toHVAD_TABLE_NAME_SEPARATOR
. Using the old name will still work for now, but issue a deprecation warning, and get removed in next version. - CSS class
nani-language-tabs
in admin templates was renamed tohvad-language-tabs
. Entities will bear both classes until next version. - Private
_real_manager
and_fallback_manager
attributes ofTranslationQueryset
have been removed as the indirection served no real purpose. - The
TranslationFallbackManager
is deprecated and will be removed in next release. Please use manager’suntranslated()
method instead. - The
TranslatableModelBase
metaclass is no longer necessary and will be removed in next release. hvad no longer triggers metaclass conflicts andTranslatableModelBase
can be safely dropped – #188. - Overriding the language in
QuerySet.get()
andQuerySet.filter()
is now deprecated. Either use thelanguage()
method to set the correct language, or specifylanguage('all')
to filter manually throughget
andfilter
– #182.
Fixes:
- Method
latest()
now works when passed no field name, properly getting the field name from the model’sMeta.get_latest_by
option. FallbackQueryset
now leverages the better control on queries allowed in Django 1.6 and newer to use only one query to resolve fallbacks. Old behavior can be forced by addingHVAD_LEGACY_FALLBACKS = True
to your settings.- Assigning value to translatable foreign keys through its
_id
field no longer results in assigned value being ignored – #193. - Tests were refactored to fully support PostgreSQL – #194
9.17. 0.4.1¶
Released on June 1, 2014
Fixes:
- Translations no longer remain in database when deleted depending on the query that deleted them – #183.
get_available_languages()
now uses translations if they were prefetched withprefetch_related()
. Especially, usingall_translations()
inlist_display
no longer results in one query per item, as long as translations were prefetched – #179, #97.
9.18. 0.4.0¶
Released on May 19, 2014
New Python and Django versions supported:
- django-hvad now supports Django 1.7 running on Python 2.7, 3.3 and 3.4.
- django-hvad now supports Django 1.6 running on Python 2.7 and 3.3.
New features:
TranslationManager
‘s queryset class can now be overriden by setting itsqueryset_class
attribute.- Proxy models can be used with django-hvad. This is a new feature, please use with caution and report any issue on github.
TranslatableAdmin
‘s list display now has direct links to each available translation.- Instance’s translated fields are now available to the model’s
save()
method when saving aTranslatableModelForm
. - Accessing a translated field on an untranslated instance will now raise an
AttributeError
with a helpful message instead of letting the exception bubble up from the ORM. - Method
in_bulk()
is now available onTranslationQueryset
.
Deprecation list:
- Catching
ObjectDoesNotExist
when accessing a translated field on an instance is deprecated. In case no translation is loaded and none exists in database for current language, anAttributeError
is raised instead. For the transition, both are supported until next release.
Removal of the old 'nani'
aliases was postponed until next release.
Fixes:
- Fixed an issue where
TranslatableAdmin
could overwrite the wrong language while saving a form. lazy_translation_getter()
now tries translations inLANGUAGES
order once it has failed with current language and site’s mainLANGUAGE_CODE
.- No more deprecation warnings when importing only from
hvad
. TranslatableAdmin
now generates relative URLs instead of absolute ones, enabling it to work behind reverse proxies.- django-hvad does not depend on the default manager being named ‘objects’ anymore.
- Q objects now work properly with
TranslationQueryset
.
9.19. 0.3¶
New Python and Django versions supported:
- django-hvad now supports Django 1.5 running on Python 2.6 and 2.6.
Deprecation list:
- Dropped support for django 1.2.
- In next release, the old ‘nani’ module will be removed.
9.20. 0.2¶
The package is now called ‘hvad’. Old imports should result in an import error.
Fixed django 1.4 support
Fixed a number of minor issues
9.22. 0.1.3 (Alpha)¶
Released on November 8, 2011
A new setting was introduced to configure the table name separator,
NANI_TABLE_NAME_SEPARATOR
.Note
If you upgrade from an earlier version, you’ll have to rename your tables yourself (the general template is
appname_modelname_translation
) or setNANI_TABLE_NAME_SEPARATOR
to the empty string in your settings (which was the implicit default until 0.1.0)
9.23. 0.0.4 (Alpha)¶
9.24. 0.0.3 (Alpha)¶
Released on May 26, 2011.
- Replaced our ghetto fallback querying code with a simplified version of the logic used in Bert Constantins django-polymorphic, all credit for our now better FallbackQueryset code goes to him.
- Replaced all JSON fixtures for testing with Python fixtures, to keep tests maintainable.
- Nicer language tabs in admin thanks to the amazing help of Angelo Dini.
- Ability to delete translations from the admin.
- Changed hvad.admin.TranslatableAdmin.get_language_tabs signature.
- Removed tests from egg.
- Fixed some tests possibly leaking client state information.
- Fixed a critical bug in hvad.forms.TranslatableModelForm where attempting to save a translated model with a relation (FK) would cause IntegrityErrors when it’s a new instance.
- Fixed a critical bug in hvad.models.TranslatableModelBase where certain field types on models would break the metaclass. (Many thanks to Kristian Oellegaard for the fix)
- Fixed a bug that prevented abstract TranslatableModel subclasses with no translated fields.
9.25. 0.0.2 (Alpha)¶
Released on May 16, 2011.
- Removed language code field from admin.
- Fixed admin ‘forgetting’ selected language when editing an instance in another language than the UI language in admin.