Values Reference

This page documents the LocalizedValue classes that handle multilingual values.

LocalizedValue

Base class for all localized value types.

class LocalizedValue(keys=None)

Dictionary-like object that stores values for multiple languages.

Parameters:

  • keys (dict | None): Dictionary of language codes to values

Attributes:

  • default_value: Default value for missing languages (None)

Methods:

get(language=None, default=None)

Get value for a specific language.

Parameters:

  • language (str | None): Language code (uses LANGUAGE_CODE if None)

  • default: Default value if not found

Returns: Value in the specified language or default

Example:

value = LocalizedValue({'en': 'Hello', 'es': 'Hola'})
print(value.get('en'))  # 'Hello'
print(value.get('fr', 'Not available'))  # 'Not available'
set(language, value)

Set value for a specific language.

Parameters:

  • language (str): Language code

  • value: Value to set

Returns: Self for chaining

Example:

value = LocalizedValue()
value.set('en', 'Hello').set('es', 'Hola')
translate(language=None)

Get value with fallback support.

Parameters:

  • language (str | None): Target language (uses active language if None)

Returns: Value in target language or fallback

Example:

# Configure fallbacks
I18N_FIELDS = {
    "FALLBACKS": {"pt-br": ["pt", "en"]}
}

value = LocalizedValue({'en': 'Hello', 'pt': 'Olá'})

with translation.override('pt-br'):
    # No pt-br, falls back to pt, then en
    print(value.translate())  # 'Olá'
is_empty()

Check if all languages contain the default value.

Returns: bool

Example:

value = LocalizedValue()
print(value.is_empty())  # True

value.set('en', 'Hello')
print(value.is_empty())  # False

Dictionary Methods:

Supports standard dictionary operations:

value = LocalizedValue({'en': 'Hello', 'es': 'Hola'})

# Access like dict
print(value['en'])  # 'Hello'

# Iterate
for lang, text in value.items():
    print(f"{lang}: {text}")

# Check membership
if 'en' in value:
    print("English available")

# Get all languages
languages = list(value.keys())

String Representation:

value = LocalizedValue({'en': 'Hello', 'es': 'Hola'})

# Returns value in current language
print(str(value))  # 'Hello' (if English is active)

with translation.override('es'):
    print(str(value))  # 'Hola'

LocalizedStringValue

class LocalizedStringValue(keys=None)

LocalizedValue with empty string as default.

Default Value: "" (empty string)

Used By:

  • LocalizedCharField

  • LocalizedTextField

Example:

from i18n_fields import LocalizedStringValue

# Create with dict
value = LocalizedStringValue({
    'en': 'Hello',
    'es': 'Hola'
})

# Missing languages return empty string
print(value.get('fr'))  # '' (not None)

# Check for value
if value.get('en'):
    print("English translation exists")

LocalizedIntegerValue

class LocalizedIntegerValue(keys=None)

LocalizedValue for integer fields.

Default Value: None

Used By: LocalizedIntegerField

Methods:

translate()

Get integer value with type conversion.

Returns: int | None

Conversion Rules:

  • int → returns as-is

  • str → converts to int (empty string returns None)

  • Other types → attempts int() conversion

  • Invalid → returns None

Magic Methods:

__int__()

Convert to integer (returns 0 if None).

Example:

from i18n_fields import LocalizedIntegerValue

value = LocalizedIntegerValue({
    'en': 100,
    'es': 50,
    'fr': '75'  # String is converted
})

print(value.translate())  # 100 (if English active)
print(int(value))  # 100

# Type conversion
print(value.get('fr'))  # Returns 75 (converted from '75')

# Missing value
print(value.get('de'))  # None

LocalizedFloatValue

class LocalizedFloatValue(keys=None)

LocalizedValue for float fields.

Default Value: None

Used By: LocalizedFloatField

Methods:

translate()

Get float value with type conversion.

Returns: float | None

Conversion Rules:

  • float or int → converts to float

  • str → converts to float (empty string returns None)

  • Other types → attempts float() conversion

  • Invalid → returns None

Magic Methods:

__float__()

Convert to float (returns 0.0 if None).

__int__()

Convert to integer (returns 0 if None).

Example:

from i18n_fields import LocalizedFloatValue

value = LocalizedFloatValue({
    'en': 99.99,
    'es': 89.99,
    'fr': '79.99'  # String is converted
})

print(value.translate())  # 99.99 (if English active)
print(float(value))  # 99.99

# Arithmetic operations
price = float(value) * 1.1  # Apply 10% markup

LocalizedBooleanValue

class LocalizedBooleanValue(keys=None)

LocalizedValue for boolean fields.

Default Value: None

Used By: LocalizedBooleanField

Methods:

translate()

Get boolean value with type conversion.

Returns: bool | None

Conversion Rules:

  • bool → returns as-is

  • str → “true” (case-insensitive) returns True, empty returns None

  • Other types → converts using bool()

Magic Methods:

__bool__()

Convert to boolean (returns False if None).

Example:

from i18n_fields import LocalizedBooleanValue

value = LocalizedBooleanValue({
    'en': True,
    'es': False,
    'fr': 'true'  # String is converted
})

print(value.translate())  # True (if English active)
print(bool(value))  # True

# Use in conditionals
if value:
    print("Value is truthy")

# Type conversion
print(value.get('fr'))  # True (converted from 'true')

LocalizedFileValue

class LocalizedFileValue(keys=None)

LocalizedValue for file fields.

Default Value: None

Used By: LocalizedFileField

Methods:

__getattr__(name)

Proxy attribute access to the current language’s file.

Returns: Attribute from the file object

Example:

from i18n_fields import LocalizedFileValue

# Assume files are uploaded
value = LocalizedFileValue({
    'en': english_file,
    'es': spanish_file
})

# Access file properties in current language
with translation.override('es'):
    url = value.url  # Proxies to spanish_file.url
    name = value.name
    size = value.size

# Direct access
en_url = value.get('en').url
es_url = value.get('es').url

Type Conversions

Automatic Conversion

LocalizedValue classes automatically convert values:

# Integer conversion
int_value = LocalizedIntegerValue({'en': '100'})
print(int_value.get('en'))  # 100 (converted from string)

# Float conversion
float_value = LocalizedFloatValue({'en': '99.99'})
print(float_value.get('en'))  # 99.99 (converted from string)

# Boolean conversion
bool_value = LocalizedBooleanValue({'en': 'true'})
print(bool_value.get('en'))  # True (converted from string)

Safe Conversion

Invalid values return None:

# Invalid integer
int_value = LocalizedIntegerValue({'en': 'not a number'})
print(int_value.get('en'))  # None

# Invalid float
float_value = LocalizedFloatValue({'en': 'invalid'})
print(float_value.get('en'))  # None

# Empty string
int_value = LocalizedIntegerValue({'en': ''})
print(int_value.get('en'))  # None

Creating Values

From Dictionary

from i18n_fields import LocalizedStringValue

value = LocalizedStringValue({
    'en': 'Hello',
    'es': 'Hola',
    'fr': 'Bonjour'
})

Using set() Method

value = LocalizedStringValue()
value.set('en', 'Hello')
value.set('es', 'Hola')
value.set('fr', 'Bonjour')

Method Chaining

value = LocalizedStringValue().set('en', 'Hello').set('es', 'Hola')

From Model Field

article = Article.objects.first()
title_value = article.title  # Already a LocalizedValue

Comparing Values

Equality

value1 = LocalizedStringValue({'en': 'Hello', 'es': 'Hola'})
value2 = LocalizedStringValue({'en': 'Hello', 'es': 'Hola'})

print(value1 == value2)  # True

# Compare with string (uses current language)
print(value1 == 'Hello')  # True (if English active)

Inequality

value1 = LocalizedStringValue({'en': 'Hello'})
value2 = LocalizedStringValue({'en': 'World'})

print(value1 != value2)  # True

Iteration

Iterate Over Languages

value = LocalizedStringValue({
    'en': 'Hello',
    'es': 'Hola',
    'fr': 'Bonjour'
})

# Iterate over items
for lang, text in value.items():
    print(f"{lang}: {text}")

# Iterate over keys
for lang in value.keys():
    print(lang)

# Iterate over values
for text in value.values():
    print(text)

Serialization

To Dictionary

value = LocalizedStringValue({'en': 'Hello', 'es': 'Hola'})

# Convert to dict
data = dict(value)
# {'en': 'Hello', 'es': 'Hola'}

For JSON

import json

value = LocalizedStringValue({'en': 'Hello', 'es': 'Hola'})

# Serialize to JSON
json_data = json.dumps(dict(value))
# '{"en": "Hello", "es": "Hola"}'

Migration Support

LocalizedValue classes support migrations:

# In migration
value = LocalizedStringValue({'en': 'Default'})
path, args, kwargs = value.deconstruct()
# path: 'i18n_fields.value.LocalizedStringValue'
# args: [{'en': 'Default'}]
# kwargs: {}

Best Practices

  1. Use translate() for User-Facing Content

    Always use translate() for fallback support:

    # Good - uses fallbacks
    display_text = article.title.translate()
    
    # Less ideal - no fallbacks
    display_text = str(article.title)
    
  2. Check for None

    Numeric and boolean values can be None:

    # Good - check for None
    price = product.price.translate()
    if price is not None:
        print(f"Price: ${price}")
    
    # Bad - may fail if None
    print(f"Price: ${product.price}")
    
  3. Use Appropriate Type

    Let the value class handle type conversion:

    # Good - automatic conversion
    stock = product.stock.get('en')  # Returns int
    
    # Unnecessary
    stock = int(product.stock.get('en'))
    
  4. Access with get() for Safety

    Use get() with default for missing languages:

    # Good - provides default
    title = article.title.get('fr', 'No translation')
    
    # May return None
    title = article.title.get('fr')
    

See Also