style: Reformat files (use double quotes)

This commit is contained in:
Serhii Tereshchenko 2023-11-25 13:35:10 +02:00
parent c8e44f56c4
commit 8742ad3554
23 changed files with 2060 additions and 2056 deletions

View file

@ -1,3 +1,4 @@
# fmt: off
# django-modeltranslation documentation build configuration file, created by
# sphinx-quickstart on Wed Oct 17 10:26:58 2012.
#
@ -59,8 +60,8 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = u'django-modeltranslation'
copyright = u'2009-2019, Peter Eschler, Dirk Eschler, Jacek Tomaszewski'
project = 'django-modeltranslation'
copyright = '2009-2019, Peter Eschler, Dirk Eschler, Jacek Tomaszewski'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -199,8 +200,8 @@ latex_elements = {
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'django-modeltranslation.tex',
u'django-modeltranslation Documentation',
u'Dirk Eschler', 'manual'),
'django-modeltranslation Documentation',
'Dirk Eschler', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@ -230,8 +231,8 @@ latex_documents = [
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'django-modeltranslation',
u'django-modeltranslation Documentation',
[u'Dirk Eschler'], 1)
'django-modeltranslation Documentation',
['Dirk Eschler'], 1)
]
# If true, show URL addresses after external links.
@ -245,7 +246,7 @@ man_pages = [
# dir menu entry, description, category)
texinfo_documents = [
('index', 'django-modeltranslation',
u'django-modeltranslation Documentation', u'Dirk Eschler',
'django-modeltranslation Documentation', 'Dirk Eschler',
'django-modeltranslation', 'One line description of project.',
'Miscellaneous'),
]
@ -263,10 +264,10 @@ texinfo_documents = [
# -- Options for Epub output --------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = u'django-modeltranslation'
epub_author = u'Dirk Eschler'
epub_publisher = u'Dirk Eschler'
epub_copyright = u'2009-2019, Peter Eschler, Dirk Eschler, Jacek Tomaszewski'
epub_title = 'django-modeltranslation'
epub_author = 'Dirk Eschler'
epub_publisher = 'Dirk Eschler'
epub_copyright = '2009-2019, Peter Eschler, Dirk Eschler, Jacek Tomaszewski'
# The language of the text. It defaults to the language option
# or en if the language is not set.

View file

@ -2,8 +2,8 @@
import sys
version = sys.argv[1]
if version.startswith('http'):
if version.startswith("http"):
print(version)
else:
next_version = version[:-1] + '%d' % (int(version[-1]) + 1)
print('Django>=%s,<%s' % (version, next_version))
next_version = version[:-1] + "%d" % (int(version[-1]) + 1)
print("Django>=%s,<%s" % (version, next_version))

View file

@ -2,6 +2,6 @@ try:
from django import VERSION as _django_version
if _django_version < (3, 2):
default_app_config = 'modeltranslation.apps.ModeltranslationConfig'
default_app_config = "modeltranslation.apps.ModeltranslationConfig"
except ImportError:
pass

View file

@ -29,18 +29,18 @@ class TranslationBaseModelAdmin(BaseModelAdmin):
def _get_declared_fieldsets(self, request, obj=None):
# Take custom modelform fields option into account
if not self.fields and hasattr(self.form, '_meta') and self.form._meta.fields:
if not self.fields and hasattr(self.form, "_meta") and self.form._meta.fields:
self.fields = self.form._meta.fields
# takes into account non-standard add_fieldsets attribute used by UserAdmin
fieldsets = (
self.add_fieldsets
if getattr(self, 'add_fieldsets', None) and obj is None
if getattr(self, "add_fieldsets", None) and obj is None
else self.fieldsets
)
if fieldsets:
return self._patch_fieldsets(fieldsets)
elif self.fields:
return [(None, {'fields': self.replace_orig_field(self.get_fields(request, obj))})]
return [(None, {"fields": self.replace_orig_field(self.get_fields(request, obj))})]
return None
def formfield_for_dbfield(self, db_field, request, **kwargs):
@ -53,7 +53,7 @@ class TranslationBaseModelAdmin(BaseModelAdmin):
if field.required:
field.required = False
field.blank = True
self._orig_was_required['%s.%s' % (db_field.model._meta, db_field.name)] = True
self._orig_was_required["%s.%s" % (db_field.model._meta, db_field.name)] = True
# For every localized field copy the widget from the original field
# and add a css class to identify a modeltranslation widget.
@ -83,24 +83,24 @@ class TranslationBaseModelAdmin(BaseModelAdmin):
b for b in form_class.__bases__ if b != NullCharField
)
field.__class__ = type(
'Nullable%s' % form_class.__name__, (NullableField, form_class), {}
"Nullable%s" % form_class.__name__, (NullableField, form_class), {}
)
if (
db_field.empty_value == 'both' or orig_field.name in self.both_empty_values_fields
db_field.empty_value == "both" or orig_field.name in self.both_empty_values_fields
) and isinstance(field.widget, (forms.TextInput, forms.Textarea)):
field.widget = ClearableWidgetWrapper(field.widget)
css_classes = self._get_widget_from_field(field).attrs.get('class', '').split(' ')
css_classes.append('mt')
css_classes = self._get_widget_from_field(field).attrs.get("class", "").split(" ")
css_classes.append("mt")
# Add localized fieldname css class
css_classes.append(build_css_class(db_field.name, 'mt-field'))
css_classes.append(build_css_class(db_field.name, "mt-field"))
# Add mt-bidi css class if language is bidirectional
if get_language_bidi(db_field.language):
css_classes.append('mt-bidi')
css_classes.append("mt-bidi")
if db_field.language == mt_settings.DEFAULT_LANGUAGE:
# Add another css class to identify a default modeltranslation widget
css_classes.append('mt-default')
css_classes.append("mt-default")
if orig_formfield.required or self._orig_was_required.get(
'%s.%s' % (orig_field.model._meta, orig_field.name)
"%s.%s" % (orig_field.model._meta, orig_field.name)
):
# In case the original form field was required, make the
# default translation field required instead.
@ -111,7 +111,7 @@ class TranslationBaseModelAdmin(BaseModelAdmin):
# Hide clearable widget for required fields
if isinstance(field.widget, ClearableWidgetWrapper):
field.widget = field.widget.widget
self._get_widget_from_field(field).attrs['class'] = ' '.join(css_classes)
self._get_widget_from_field(field).attrs["class"] = " ".join(css_classes)
def _get_widget_from_field(self, field):
# retrieve "nested" widget in case of related field
@ -171,8 +171,8 @@ class TranslationBaseModelAdmin(BaseModelAdmin):
if fieldsets:
fieldsets_new = list(fieldsets)
for name, dct in fieldsets:
if 'fields' in dct:
dct['fields'] = self.replace_orig_field(dct['fields'])
if "fields" in dct:
dct["fields"] = self.replace_orig_field(dct["fields"])
fieldsets = fieldsets_new
return fieldsets
@ -208,7 +208,7 @@ class TranslationBaseModelAdmin(BaseModelAdmin):
else:
exclude = list(exclude)
exclude.extend(self.get_readonly_fields(request, obj))
if not exclude and hasattr(self.form, '_meta') and self.form._meta.exclude:
if not exclude and hasattr(self.form, "_meta") and self.form._meta.exclude:
# Take the custom ModelForm's Meta.exclude into account only if the
# ModelAdmin doesn't define its own.
exclude.extend(self.form._meta.exclude)
@ -216,7 +216,7 @@ class TranslationBaseModelAdmin(BaseModelAdmin):
# default on modelform_factory
exclude = self.replace_orig_field(exclude) or None
exclude = self._exclude_original_fields(exclude)
kwargs.update({'exclude': exclude})
kwargs.update({"exclude": exclude})
return kwargs
@ -234,7 +234,7 @@ class TranslationBaseModelAdmin(BaseModelAdmin):
"""
base_fields = self.replace_orig_field(form.base_fields.keys())
fields = list(base_fields) + list(self.get_readonly_fields(request, obj))
return [(None, {'fields': self.replace_orig_field(fields)})]
return [(None, {"fields": self.replace_orig_field(fields)})]
def get_translation_field_excludes(self, exclude_languages=None):
"""
@ -296,13 +296,14 @@ class TranslationAdmin(TranslationBaseModelAdmin, admin.ModelAdmin):
untranslated_fields = [
f.name
for f in fields
if (
if
(
# Exclude the primary key field
f is not self.opts.auto_field
# Exclude non-editable fields
and f.editable
# Exclude the translation fields
and not hasattr(f, 'translated_field')
and not hasattr(f, "translated_field")
# Honour field arguments. We rely on the fact that the
# passed fieldsets argument is already fully filtered
# and takes options like exclude into account.
@ -313,8 +314,8 @@ class TranslationAdmin(TranslationBaseModelAdmin, admin.ModelAdmin):
fieldsets = (
[
(
'',
{'fields': untranslated_fields},
"",
{"fields": untranslated_fields},
)
]
if untranslated_fields
@ -331,13 +332,13 @@ class TranslationAdmin(TranslationBaseModelAdmin, admin.ModelAdmin):
label = self.model._meta.get_field(orig_field).verbose_name.capitalize()
temp_fieldsets[orig_field] = (
label,
{'fields': trans_fieldnames, 'classes': ('mt-fieldset',)},
{"fields": trans_fieldnames, "classes": ("mt-fieldset",)},
)
fields_order = unique(
f.translated_field.name
for f in self.opts.fields
if hasattr(f, 'translated_field') and f.name in flattened_fieldsets
if hasattr(f, "translated_field") and f.name in flattened_fieldsets
)
for field_name in fields_order:
fieldsets.append(temp_fieldsets.pop(field_name))
@ -397,13 +398,13 @@ class TabbedDjangoJqueryTranslationAdmin(TranslationAdmin):
class Media:
js = (
'admin/js/jquery.init.js',
'modeltranslation/js/force_jquery.js',
"admin/js/jquery.init.js",
"modeltranslation/js/force_jquery.js",
mt_settings.JQUERY_UI_URL,
'modeltranslation/js/tabbed_translation_fields.js',
"modeltranslation/js/tabbed_translation_fields.js",
)
css = {
'all': ('modeltranslation/css/tabbed_translation_fields.css',),
"all": ("modeltranslation/css/tabbed_translation_fields.css",),
}
@ -417,10 +418,10 @@ class TabbedExternalJqueryTranslationAdmin(TranslationAdmin):
js = (
mt_settings.JQUERY_URL,
mt_settings.JQUERY_UI_URL,
'modeltranslation/js/tabbed_translation_fields.js',
"modeltranslation/js/tabbed_translation_fields.js",
)
css = {
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
"screen": ("modeltranslation/css/tabbed_translation_fields.css",),
}

View file

@ -2,8 +2,8 @@ from django.apps import AppConfig
class ModeltranslationConfig(AppConfig):
name = 'modeltranslation'
verbose_name = 'Modeltranslation'
name = "modeltranslation"
verbose_name = "Modeltranslation"
def ready(self):
from modeltranslation.models import handle_translation_registrations

View file

@ -70,12 +70,12 @@ def create_translation_field(model, field_name, lang, empty_value):
If the class is neither a subclass of fields in ``SUPPORTED_FIELDS``, nor
in ``CUSTOM_FIELDS`` an ``ImproperlyConfigured`` exception will be raised.
"""
if empty_value not in ('', 'both', None, NONE):
raise ImproperlyConfigured('%s is not a valid empty_value.' % empty_value)
if empty_value not in ("", "both", None, NONE):
raise ImproperlyConfigured("%s is not a valid empty_value." % empty_value)
field = model._meta.get_field(field_name)
cls_name = field.__class__.__name__
if not (isinstance(field, SUPPORTED_FIELDS) or cls_name in mt_settings.CUSTOM_FIELDS):
raise ImproperlyConfigured('%s is not supported by modeltranslation.' % cls_name)
raise ImproperlyConfigured("%s is not supported by modeltranslation." % cls_name)
translation_class = field_factory(field.__class__)
return translation_class(translated_field=field, language=lang, empty_value=empty_value)
@ -85,7 +85,7 @@ def field_factory(baseclass):
pass
# Reflect baseclass name of returned subclass
TranslationFieldSpecific.__name__ = 'Translation%s' % baseclass.__name__
TranslationFieldSpecific.__name__ = "Translation%s" % baseclass.__name__
return TranslationFieldSpecific
@ -121,7 +121,7 @@ class TranslationField:
self.language = language
self.empty_value = empty_value
if empty_value is NONE:
self.empty_value = None if translated_field.null else ''
self.empty_value = None if translated_field.null else ""
# Default behaviour is that all translations are optional
if not isinstance(self, fields.BooleanField):
@ -145,7 +145,7 @@ class TranslationField:
try:
req_fields = required_languages[self.language]
except KeyError:
req_fields = required_languages.get('default', ())
req_fields = required_languages.get("default", ())
if self.name in req_fields:
# TODO: We might have to handle the whole thing through the
# FieldsAggregationMetaClass, as fields can be inherited.
@ -205,7 +205,7 @@ class TranslationField:
)
self.remote_field.field = self
if hasattr(self.remote_field.model._meta, '_related_objects_cache'):
if hasattr(self.remote_field.model._meta, "_related_objects_cache"):
del self.remote_field.model._meta._related_objects_cache
# ForeignKey support - rewrite related_name
@ -223,7 +223,7 @@ class TranslationField:
self.related_query_name = lambda: loc_related_query_name
self.rel.related_name = build_localized_fieldname(current, self.language)
self.rel.field = self
if hasattr(self.rel.to._meta, '_related_objects_cache'):
if hasattr(self.rel.to._meta, "_related_objects_cache"):
del self.rel.to._meta._related_objects_cache
elif NEW_RELATED_API and self.remote_field and not self.remote_field.is_hidden():
current = self.remote_field.get_accessor_name()
@ -238,7 +238,7 @@ class TranslationField:
self.related_query_name = lambda: loc_related_query_name
self.remote_field.related_name = build_localized_fieldname(current, self.language)
self.remote_field.field = self
if hasattr(self.remote_field.model._meta, '_related_objects_cache'):
if hasattr(self.remote_field.model._meta, "_related_objects_cache"):
del self.remote_field.model._meta._related_objects_cache
# Django 1.5 changed definition of __hash__ for fields to be fine with hash requirements.
@ -249,7 +249,7 @@ class TranslationField:
def __eq__(self, other):
if isinstance(other, fields.Field):
return self.creation_counter == other.creation_counter and self.language == getattr(
other, 'language', None
other, "language", None
)
return super().__eq__(other)
@ -301,16 +301,16 @@ class TranslationField:
from modeltranslation.forms import NullCharField
form_class = formfield.__class__
kwargs['form_class'] = type(
'Null%s' % form_class.__name__, (NullCharField, form_class), {}
kwargs["form_class"] = type(
"Null%s" % form_class.__name__, (NullCharField, form_class), {}
)
formfield = super().formfield(*args, **kwargs)
elif self.empty_value == 'both':
elif self.empty_value == "both":
from modeltranslation.forms import NullableField
form_class = formfield.__class__
kwargs['form_class'] = type(
'Nullable%s' % form_class.__name__, (NullableField, form_class), {}
kwargs["form_class"] = type(
"Nullable%s" % form_class.__name__, (NullableField, form_class), {}
)
formfield = super().formfield(*args, **kwargs)
if isinstance(formfield.widget, (forms.TextInput, forms.Textarea)):
@ -328,7 +328,7 @@ class TranslationField:
# Questionable fields are stored in special variable, which is later handled by clean_fields
# method on the model.
if check and self.language == get_language() and getattr(instance, self.name) and not data:
if not hasattr(instance, '_mt_form_pending_clear'):
if not hasattr(instance, "_mt_form_pending_clear"):
instance._mt_form_pending_clear = {}
instance._mt_form_pending_clear[self.name] = data
else:
@ -337,9 +337,9 @@ class TranslationField:
def deconstruct(self):
name, path, args, kwargs = self.translated_field.deconstruct()
if self.null is True:
kwargs.update({'null': True})
if 'db_column' in kwargs:
kwargs['db_column'] = self.db_column
kwargs.update({"null": True})
if "db_column" in kwargs:
kwargs["db_column"] = self.db_column
return self.name, path, args, kwargs
def clone(self):
@ -375,7 +375,7 @@ class TranslationFieldDescriptor:
instance.__dict__[self.field.name] = value
if isinstance(self.field, fields.related.ForeignKey):
instance.__dict__[self.field.get_attname()] = None if value is None else value.pk
if getattr(instance, '_mt_init', False) or getattr(instance, '_mt_disable', False):
if getattr(instance, "_mt_init", False) or getattr(instance, "_mt_disable", False):
# When assignment takes place in model instance constructor, don't set value.
# This is essential for only/defer to work, but I think it's sensible anyway.
# Setting the localized field may also be disabled by setting _mt_disable.

View file

@ -42,7 +42,7 @@ class NullableField(forms.Field):
if (initial is None and data is not None) or (initial is not None and data is None):
return True
obj = super()
if hasattr(obj, 'has_changed'):
if hasattr(obj, "has_changed"):
return obj.has_changed(initial, data)
else: # Django < 1.9 compat
return obj._has_changed(initial, data)

View file

@ -7,12 +7,12 @@ from django.core.management.commands.loaddata import Command as LoadDataCommand
from modeltranslation import settings as mt_settings
from modeltranslation.utils import auto_populate
ALLOWED = (None, False, 'all', 'default', 'required')
ALLOWED_FOR_PRINT = ', '.join(str(i) for i in (0,) + ALLOWED[1:]) # For pretty-printing
ALLOWED = (None, False, "all", "default", "required")
ALLOWED_FOR_PRINT = ", ".join(str(i) for i in (0,) + ALLOWED[1:]) # For pretty-printing
def check_mode(option, opt_str, value, parser, namespace=None):
if value == '0' or value.lower() == 'false':
if value == "0" or value.lower() == "false":
value = False
if value not in ALLOWED:
raise ValueError("%s option can be only one of: %s" % (opt_str, ALLOWED_FOR_PRINT))
@ -29,19 +29,19 @@ class Command(LoadDataCommand):
def add_arguments(self, parser):
super().add_arguments(parser)
parser.add_argument(
'--populate',
"--populate",
action=self.CheckAction,
type=str,
dest='populate',
metavar='MODE',
dest="populate",
metavar="MODE",
help=(
'Using this option will cause fixtures to be loaded under auto-population MODE. '
+ 'Allowed values are: %s' % ALLOWED_FOR_PRINT
"Using this option will cause fixtures to be loaded under auto-population MODE. "
+ "Allowed values are: %s" % ALLOWED_FOR_PRINT
),
)
def handle(self, *fixture_labels, **options):
mode = options.get('populate')
mode = options.get("populate")
if mode is not None:
with auto_populate(mode):
return super().handle(*fixture_labels, **options)

View file

@ -21,18 +21,18 @@ from modeltranslation.utils import build_localized_fieldname
def ask_for_confirmation(sql_sentences, model_full_name, interactive):
print('\nSQL to synchronize "%s" schema:' % model_full_name)
for sentence in sql_sentences:
print(' %s' % sentence)
print(" %s" % sentence)
while True:
prompt = '\nAre you sure that you want to execute the previous SQL: (y/n) [n]: '
prompt = "\nAre you sure that you want to execute the previous SQL: (y/n) [n]: "
if interactive:
answer = input(prompt).strip()
else:
answer = 'y'
if answer == '':
answer = "y"
if answer == "":
return False
elif answer not in ('y', 'n', 'yes', 'no'):
print('Please answer yes or no')
elif answer == 'y' or answer == 'yes':
elif answer not in ("y", "n", "yes", "no"):
print("Please answer yes or no")
elif answer == "y" or answer == "yes":
return True
else:
return False
@ -47,9 +47,9 @@ def print_missing_langs(missing_langs, field_name, model_name):
class Command(BaseCommand):
help = (
'Detect new translatable fields or new available languages and'
' sync database structure. Does not remove columns of removed'
' languages or undeclared fields.'
"Detect new translatable fields or new available languages and"
" sync database structure. Does not remove columns of removed"
" languages or undeclared fields."
)
if VERSION < (1, 8):
@ -57,23 +57,25 @@ class Command(BaseCommand):
option_list = BaseCommand.option_list + (
make_option(
'--noinput',
action='store_false',
dest='interactive',
"--noinput",
action="store_false",
dest="interactive",
default=True,
help='Do NOT prompt the user for input of any kind.',
help="Do NOT prompt the user for input of any kind.",
),
)
else:
def add_arguments(self, parser):
parser.add_argument(
'--noinput',
action='store_false',
dest='interactive',
default=True,
help='Do NOT prompt the user for input of any kind.',
),
(
parser.add_argument(
"--noinput",
action="store_false",
dest="interactive",
default=True,
help="Do NOT prompt the user for input of any kind.",
),
)
def handle(self, *args, **options):
"""
@ -81,14 +83,14 @@ class Command(BaseCommand):
"""
self.cursor = connection.cursor()
self.introspection = connection.introspection
self.interactive = options['interactive']
self.interactive = options["interactive"]
found_missing_fields = False
models = translator.get_registered_models(abstract=False)
for model in models:
db_table = model._meta.db_table
model_name = model._meta.model_name
model_full_name = '%s.%s' % (model._meta.app_label, model_name)
model_full_name = "%s.%s" % (model._meta.app_label, model_name)
opts = translator.get_options_for_model(model)
for field_name, fields in opts.local_fields.items():
# Take `db_column` attribute into account
@ -108,15 +110,15 @@ class Command(BaseCommand):
sql_sentences, model_full_name, self.interactive
)
if execute_sql:
print('Executing SQL...')
print("Executing SQL...")
for sentence in sql_sentences:
self.cursor.execute(sentence)
print('Done')
print("Done")
else:
print('SQL not executed')
print("SQL not executed")
if not found_missing_fields:
print('No new translatable fields detected')
print("No new translatable fields detected")
def get_table_fields(self, db_table):
"""
@ -148,8 +150,8 @@ class Command(BaseCommand):
col_type = f.db_type(connection=connection)
field_sql = [style.SQL_FIELD(qn(f.column)), style.SQL_COLTYPE(col_type)]
# column creation
stmt = "ALTER TABLE %s ADD COLUMN %s" % (qn(db_table), ' '.join(field_sql))
stmt = "ALTER TABLE %s ADD COLUMN %s" % (qn(db_table), " ".join(field_sql))
if not f.null:
stmt += " " + style.SQL_KEYWORD('NOT NULL')
stmt += " " + style.SQL_KEYWORD("NOT NULL")
sql_output.append(stmt + ";")
return sql_output

View file

@ -10,32 +10,32 @@ COMMASPACE = ", "
class Command(BaseCommand):
help = (
'Updates empty values of translation fields using'
' values from original fields (in all translated models).'
"Updates empty values of translation fields using"
" values from original fields (in all translated models)."
)
def add_arguments(self, parser):
parser.add_argument(
'app_label',
nargs='?',
help='App label of an application to update empty values.',
"app_label",
nargs="?",
help="App label of an application to update empty values.",
)
parser.add_argument(
'model_name',
nargs='?',
help='Model name to update empty values of only this model.',
"model_name",
nargs="?",
help="Model name to update empty values of only this model.",
)
parser.add_argument(
'--language',
action='store',
"--language",
action="store",
help=(
'Language translation field the be updated.'
' Default language field if not provided'
"Language translation field the be updated."
" Default language field if not provided"
),
)
def handle(self, *args, **options):
verbosity = options['verbosity']
verbosity = options["verbosity"]
if verbosity > 0:
self.stdout.write("Using default language: %s" % DEFAULT_LANGUAGE)
@ -44,30 +44,30 @@ class Command(BaseCommand):
models = [m for m in models if not m._meta.proxy and m._meta.managed]
# optionally filter by given app_label
app_label = options['app_label']
app_label = options["app_label"]
if app_label:
models = [m for m in models if m._meta.app_label == app_label]
# optionally filter by given model_name
model_name = options['model_name']
model_name = options["model_name"]
if model_name:
model_name = model_name.lower()
models = [m for m in models if m._meta.model_name == model_name]
# optionally defining the translation field language
lang = options.get('language') or DEFAULT_LANGUAGE
lang = options.get("language") or DEFAULT_LANGUAGE
if lang not in AVAILABLE_LANGUAGES:
raise CommandError(
"Cannot find language '%s'. Options are %s."
% (lang, COMMASPACE.join(AVAILABLE_LANGUAGES))
)
else:
lang = lang.replace('-', '_')
lang = lang.replace("-", "_")
if verbosity > 0:
self.stdout.write(
"Working on models: %s"
% ', '.join(
% ", ".join(
["{app_label}.{object_name}".format(**m._meta.__dict__) for m in models]
)
)

View file

@ -43,7 +43,7 @@ def get_translatable_fields_for_model(model):
def rewrite_lookup_key(model, lookup_key):
try:
pieces = lookup_key.split('__', 1)
pieces = lookup_key.split("__", 1)
original_key = pieces[0]
translatable_fields = get_translatable_fields_for_model(model)
@ -61,7 +61,7 @@ def rewrite_lookup_key(model, lookup_key):
if original_key in fields_to_trans_models:
transmodel = fields_to_trans_models[original_key]
pieces[1] = rewrite_lookup_key(transmodel, pieces[1])
return '__'.join(pieces)
return "__".join(pieces)
except AttributeError:
return lookup_key
@ -99,7 +99,7 @@ def append_translated(model, fields):
def append_lookup_key(model, lookup_key):
"Transform spanned__lookup__key into all possible translation versions, on all levels"
pieces = lookup_key.split('__', 1)
pieces = lookup_key.split("__", 1)
fields = append_translated(model, (pieces[0],))
@ -109,9 +109,9 @@ def append_lookup_key(model, lookup_key):
if pieces[0] in fields_to_trans_models:
transmodel = fields_to_trans_models[pieces[0]]
rest = append_lookup_key(transmodel, pieces[1])
fields = {'__'.join(pr) for pr in itertools.product(fields, rest)}
fields = {"__".join(pr) for pr in itertools.product(fields, rest)}
else:
fields = {'%s__%s' % (f, pieces[1]) for f in fields}
fields = {"%s__%s" % (f, pieces[1]) for f in fields}
return fields
@ -129,8 +129,8 @@ def append_lookup_keys(model, fields):
def rewrite_order_lookup_key(model, lookup_key):
try:
if lookup_key.startswith('-'):
return '-' + rewrite_lookup_key(model, lookup_key[1:])
if lookup_key.startswith("-"):
return "-" + rewrite_lookup_key(model, lookup_key[1:])
else:
return rewrite_lookup_key(model, lookup_key)
except AttributeError:
@ -201,12 +201,12 @@ class MultilingualQuerySet(QuerySet):
# This method is private, so outside code can use default _clone without `kwargs`,
# and we're here can use private version with `kwargs`.
# Refs: https://github.com/deschler/django-modeltranslation/issues/483
kwargs.setdefault('_rewrite', self._rewrite)
kwargs.setdefault('_populate', self._populate)
if hasattr(self, 'translation_fields'):
kwargs.setdefault('translation_fields', self.translation_fields)
if hasattr(self, 'original_fields'):
kwargs.setdefault('original_fields', self.original_fields)
kwargs.setdefault("_rewrite", self._rewrite)
kwargs.setdefault("_populate", self._populate)
if hasattr(self, "translation_fields"):
kwargs.setdefault("translation_fields", self.translation_fields)
if hasattr(self, "original_fields"):
kwargs.setdefault("original_fields", self.original_fields)
cloned = super()._clone()
cloned.__dict__.update(kwargs)
return cloned
@ -214,7 +214,7 @@ class MultilingualQuerySet(QuerySet):
def rewrite(self, mode=True):
return self.__clone(_rewrite=mode)
def populate(self, mode='all'):
def populate(self, mode="all"):
"""
Overrides the translation fields population mode for this query set.
"""
@ -255,9 +255,9 @@ class MultilingualQuerySet(QuerySet):
if col.target is col.source:
col.source = new_field
col.target = new_field
elif hasattr(col, 'col'):
elif hasattr(col, "col"):
self._rewrite_col(col.col)
elif hasattr(col, 'lhs'):
elif hasattr(col, "lhs"):
self._rewrite_col(col.lhs)
def _rewrite_where(self, q):
@ -302,9 +302,9 @@ class MultilingualQuerySet(QuerySet):
if isinstance(q, Node):
q.children = list(map(self._rewrite_f, q.children))
# Django >= 1.8
if hasattr(q, 'lhs'):
if hasattr(q, "lhs"):
q.lhs = self._rewrite_f(q.lhs)
if hasattr(q, 'rhs'):
if hasattr(q, "rhs"):
q.rhs = self._rewrite_f(q.rhs)
return q
@ -333,7 +333,7 @@ class MultilingualQuerySet(QuerySet):
def _get_original_fields(self):
source = (
self.model._meta.concrete_fields
if hasattr(self.model._meta, 'concrete_fields')
if hasattr(self.model._meta, "concrete_fields")
else self.model._meta.fields
)
return [f.attname for f in source if not isinstance(f, TranslationField)]
@ -433,8 +433,8 @@ class MultilingualQuerySet(QuerySet):
return super().values(*fields, **expressions)
def _values(self, *original, **kwargs):
selects_all = kwargs.pop('selects_all', False)
if not kwargs.pop('prepare', False):
selects_all = kwargs.pop("selects_all", False)
if not kwargs.pop("prepare", False):
return super()._values(*original, **kwargs)
new_fields, translation_fields = append_fallback(self.model, original)
annotation_keys = set(self.query.annotation_select.keys()) if selects_all else set()
@ -472,13 +472,13 @@ class MultilingualQuerySet(QuerySet):
# Emulate original queryset behaviour: get all fields that are not translation fields
fields = self._get_original_fields()
field_names = {f for f in fields if not hasattr(f, 'resolve_expression')}
field_names = {f for f in fields if not hasattr(f, "resolve_expression")}
_fields = []
expressions = {}
counter = 1
for field in fields:
if hasattr(field, 'resolve_expression'):
field_id_prefix = getattr(field, 'default_alias', field.__class__.__name__.lower())
if hasattr(field, "resolve_expression"):
field_id_prefix = getattr(field, "default_alias", field.__class__.__name__.lower())
while True:
field_id = field_id_prefix + str(counter)
counter += 1
@ -555,7 +555,7 @@ def multilingual_queryset_factory(old_cls, instantiate=True):
class NewClass(old_cls, MultilingualQuerySet):
pass
NewClass.__name__ = 'Multilingual%s' % old_cls.__name__
NewClass.__name__ = "Multilingual%s" % old_cls.__name__
return NewClass() if instantiate else NewClass

View file

@ -19,7 +19,7 @@ def autodiscover():
for app, mod in mods:
# Attempt to import the app's translation module.
module = '%s.translation' % app
module = "%s.translation" % app
before_import_registry = copy.copy(translator._registry)
try:
import_module(module)
@ -32,7 +32,7 @@ def autodiscover():
# Decide whether to bubble up this error. If the app just
# doesn't have an translation module, we can ignore the error
# attempting to import it, otherwise we want it to bubble up.
if module_has_submodule(mod, 'translation'):
if module_has_submodule(mod, "translation"):
raise
for module in TRANSLATION_FILES:
@ -46,12 +46,12 @@ def autodiscover():
# order, as far as base classes are registered before subclasses.
if DEBUG:
try:
if sys.argv[1] in ('runserver', 'runserver_plus'):
if sys.argv[1] in ("runserver", "runserver_plus"):
models = translator.get_registered_models()
names = ', '.join(m.__name__ for m in models)
names = ", ".join(m.__name__ for m in models)
print(
'modeltranslation: Registered %d models for translation'
' (%s) [pid: %d].' % (len(models), names, os.getpid())
"modeltranslation: Registered %d models for translation"
" (%s) [pid: %d]." % (len(models), names, os.getpid())
)
except IndexError:
pass

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,7 @@ from modeltranslation.manager import MultilingualManager
class TestModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
text = models.TextField(blank=True, null=True)
url = models.URLField(blank=True, null=True)
email = models.EmailField(blank=True, null=True)
@ -33,7 +33,7 @@ class ProxyTestModel(TestModel):
class FallbackModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
text = models.TextField(blank=True, null=True)
url = models.URLField(blank=True, null=True)
email = models.EmailField(blank=True, null=True)
@ -41,7 +41,7 @@ class FallbackModel(models.Model):
class FallbackModel2(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
text = models.TextField(blank=True, null=True)
url = models.URLField(blank=True, null=True)
email = models.EmailField(blank=True, null=True)
@ -51,21 +51,21 @@ class FallbackModel2(models.Model):
class FileFieldsModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
file = models.FileField(upload_to='modeltranslation_tests', null=True, blank=True)
file2 = models.FileField(upload_to='modeltranslation_tests')
image = models.ImageField(upload_to='modeltranslation_tests', null=True, blank=True)
title = models.CharField(gettext_lazy("title"), max_length=255)
file = models.FileField(upload_to="modeltranslation_tests", null=True, blank=True)
file2 = models.FileField(upload_to="modeltranslation_tests")
image = models.ImageField(upload_to="modeltranslation_tests", null=True, blank=True)
# ######### Foreign Key / OneToOneField / ManytoManyField testing
class NonTranslated(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
class ForeignKeyModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
test = models.ForeignKey(
TestModel,
null=True,
@ -97,7 +97,7 @@ class ForeignKeyModel(models.Model):
class OneToOneFieldModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
test = models.OneToOneField(
TestModel,
null=True,
@ -116,7 +116,7 @@ class OneToOneFieldModel(models.Model):
class ManyToManyFieldModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
test = models.ManyToManyField(
TestModel,
related_name="m2m_test_ref",
@ -184,8 +184,8 @@ class FancyDescriptor:
def __get__(self, instance, owner):
length = instance.__dict__[self.field.name]
if length is None:
return ''
return 'a' * length
return ""
return "a" * length
def __set__(self, obj, value):
if isinstance(value, int):
@ -198,7 +198,7 @@ class FancyDescriptor:
class FancyField(models.PositiveIntegerField):
def __init__(self, *args, **kwargs):
kwargs.setdefault('default', '')
kwargs.setdefault("default", "")
super().__init__(*args, **kwargs)
def contribute_to_class(self, cls, name):
@ -222,41 +222,41 @@ class DescriptorModel(models.Model):
class MultitableModelA(models.Model):
titlea = models.CharField(gettext_lazy('title a'), max_length=255)
titlea = models.CharField(gettext_lazy("title a"), max_length=255)
class MultitableModelB(MultitableModelA):
titleb = models.CharField(gettext_lazy('title b'), max_length=255)
titleb = models.CharField(gettext_lazy("title b"), max_length=255)
class MultitableModelC(MultitableModelB):
titlec = models.CharField(gettext_lazy('title c'), max_length=255)
titlec = models.CharField(gettext_lazy("title c"), max_length=255)
class MultitableModelD(MultitableModelB):
titled = models.CharField(gettext_lazy('title d'), max_length=255)
titled = models.CharField(gettext_lazy("title d"), max_length=255)
# ######### Abstract inheritance testing
class AbstractModelA(models.Model):
titlea = models.CharField(gettext_lazy('title a'), max_length=255)
titlea = models.CharField(gettext_lazy("title a"), max_length=255)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.titlea = 'title_a'
self.titlea = "title_a"
class Meta:
abstract = True
class AbstractModelB(AbstractModelA):
titleb = models.CharField(gettext_lazy('title b'), max_length=255)
titleb = models.CharField(gettext_lazy("title b"), max_length=255)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.titleb = 'title_b'
self.titleb = "title_b"
# ######### Fields inheritance testing
@ -341,12 +341,12 @@ class FilteredManager(MultilingualManager):
class FilteredTestModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
objects = FilteredManager()
class ForeignKeyFilteredModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
test = models.ForeignKey(
FilteredTestModel,
null=True,
@ -356,28 +356,28 @@ class ForeignKeyFilteredModel(models.Model):
class ManagerTestModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
visits = models.IntegerField(gettext_lazy('visits'), default=0)
title = models.CharField(gettext_lazy("title"), max_length=255)
visits = models.IntegerField(gettext_lazy("visits"), default=0)
description = models.CharField(max_length=255, null=True)
class Meta:
ordering = ('-visits',)
ordering = ("-visits",)
class CustomManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(title__contains='a').exclude(description__contains='x')
return super().get_queryset().filter(title__contains="a").exclude(description__contains="x")
def custom_qs(self):
return super().get_queryset()
def foo(self):
return 'bar'
return "bar"
class CustomManagerTestModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
description = models.CharField(max_length=255, null=True, db_column='xyz')
title = models.CharField(gettext_lazy("title"), max_length=255)
description = models.CharField(max_length=255, null=True, db_column="xyz")
objects = CustomManager()
another_mgr_name = CustomManager()
@ -393,7 +393,7 @@ class CustomManager2(models.Manager):
class CustomManager2TestModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
objects = CustomManager2()
@ -412,13 +412,13 @@ class CustomManagerBaseModel(models.Model):
class CustomManagerChildTestModel(CustomManagerBaseModel):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
objects = CustomManager2()
class PlainChildTestModel(CustomManagerBaseModel):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
# ######### Required fields testing
@ -435,7 +435,7 @@ class RequiredModel(models.Model):
class ConflictModel(models.Model):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
title_de = models.IntegerField()
@ -447,7 +447,7 @@ class AbstractConflictModelA(models.Model):
class AbstractConflictModelB(AbstractConflictModelA):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
class MultitableConflictModelA(models.Model):
@ -455,7 +455,7 @@ class MultitableConflictModelA(models.Model):
class MultitableConflictModelB(MultitableConflictModelA):
title = models.CharField(gettext_lazy('title'), max_length=255)
title = models.CharField(gettext_lazy("title"), max_length=255)
# ######### Complex M2M with abstract classes and custom managers
@ -488,8 +488,8 @@ class ModelX(AbstractModelX):
class AbstractModelXY(models.Model):
model_x = models.ForeignKey('ModelX', on_delete=models.CASCADE)
model_y = models.ForeignKey('ModelY', on_delete=models.CASCADE)
model_x = models.ForeignKey("ModelX", on_delete=models.CASCADE)
model_y = models.ForeignKey("ModelY", on_delete=models.CASCADE)
class Meta:
abstract = True
@ -505,7 +505,7 @@ class CustomManagerY(models.Manager):
class AbstractModelY(models.Model):
title = models.CharField(max_length=255)
xs = models.ManyToManyField('ModelX', through='ModelXY')
xs = models.ManyToManyField("ModelX", through="ModelXY")
objects = CustomManagerY()
class Meta:

View file

@ -4,7 +4,7 @@ from .test_app.models import Other
class OtherTranslationOptions(TranslationOptions):
fields = ('name',)
fields = ("name",)
translator.register(Other, OtherTranslationOptions)

View file

@ -1,37 +1,37 @@
import os
import warnings
warnings.simplefilter('always', DeprecationWarning)
warnings.simplefilter("always", DeprecationWarning)
def _get_database_config():
db = os.getenv('DB', 'sqlite')
host = os.getenv('DB_HOST', 'localhost')
db = os.getenv("DB", "sqlite")
host = os.getenv("DB_HOST", "localhost")
conf = {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:',
'TEST': {
'SERIALIZE': False,
"ENGINE": "django.db.backends.sqlite3",
"NAME": ":memory:",
"TEST": {
"SERIALIZE": False,
},
}
if db == 'mysql':
if db == "mysql":
conf.update(
{
'ENGINE': 'django.db.backends.mysql',
'NAME': os.getenv('MYSQL_DATABASE', 'modeltranslation'),
'USER': os.getenv('MYSQL_USER', 'root'),
'PASSWORD': os.getenv('MYSQL_PASSWORD', 'password'),
'HOST': host,
"ENGINE": "django.db.backends.mysql",
"NAME": os.getenv("MYSQL_DATABASE", "modeltranslation"),
"USER": os.getenv("MYSQL_USER", "root"),
"PASSWORD": os.getenv("MYSQL_PASSWORD", "password"),
"HOST": host,
}
)
elif db == 'postgres':
elif db == "postgres":
conf.update(
{
'ENGINE': 'django.db.backends.postgresql',
'USER': os.getenv('POSTGRES_USER', 'postgres'),
'PASSWORD': os.getenv('POSTGRES_PASSWORD', 'postgres'),
'NAME': os.getenv('POSTGRES_DB', 'modeltranslation'),
'HOST': host,
"ENGINE": "django.db.backends.postgresql",
"USER": os.getenv("POSTGRES_USER", "postgres"),
"PASSWORD": os.getenv("POSTGRES_PASSWORD", "postgres"),
"NAME": os.getenv("POSTGRES_DB", "modeltranslation"),
"HOST": host,
}
)
return conf
@ -40,23 +40,23 @@ def _get_database_config():
DATABASES = {"default": _get_database_config()}
INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.auth',
'modeltranslation',
'modeltranslation.tests',
"django.contrib.contenttypes",
"django.contrib.auth",
"modeltranslation",
"modeltranslation.tests",
)
LANGUAGES = (('de', 'Deutsch'), ('en', 'English'))
LANGUAGE_CODE = 'de'
LANGUAGES = (("de", "Deutsch"), ("en", "English"))
LANGUAGE_CODE = "de"
USE_I18N = True
USE_TZ = False
MIDDLEWARE_CLASSES = ()
MODELTRANSLATION_DEFAULT_LANGUAGE = 'de'
MODELTRANSLATION_DEFAULT_LANGUAGE = "de"
MODELTRANSLATION_AUTO_POPULATE = False
MODELTRANSLATION_FALLBACK_LANGUAGES = ()
ROOT_URLCONF = 'modeltranslation.tests.urls'
ROOT_URLCONF = "modeltranslation.tests.urls"
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

View file

@ -3,7 +3,7 @@ from django.db import models
class News(models.Model):
class Meta:
app_label = 'test_app'
app_label = "test_app"
title = models.CharField(max_length=50)
visits = models.SmallIntegerField(blank=True, null=True)
@ -11,6 +11,6 @@ class News(models.Model):
class Other(models.Model):
class Meta:
app_label = 'test_app'
app_label = "test_app"
name = models.CharField(max_length=50)

View file

@ -4,7 +4,7 @@ from .models import News
class NewsTranslationOptions(TranslationOptions):
fields = ('title',)
fields = ("title",)
translator.register(News, NewsTranslationOptions)

File diff suppressed because it is too large Load diff

View file

@ -10,18 +10,18 @@ from modeltranslation.translator import TranslationOptions, register, translator
@register(models.TestModel)
class TestTranslationOptions(TranslationOptions):
fields = (
'title',
'text',
'url',
'email',
'dynamic_default',
"title",
"text",
"url",
"email",
"dynamic_default",
)
empty_values = ''
empty_values = ""
@register(models.UniqueNullableModel)
class UniqueNullableTranslationOptions(TranslationOptions):
fields = ('title',)
fields = ("title",)
# ######### Proxy model testing
@ -30,10 +30,10 @@ class UniqueNullableTranslationOptions(TranslationOptions):
@register(models.ProxyTestModel)
class ProxyTestTranslationOptions(TranslationOptions):
fields = (
'title',
'text',
'url',
'email',
"title",
"text",
"url",
"email",
)
@ -42,20 +42,20 @@ class ProxyTestTranslationOptions(TranslationOptions):
@register(models.FallbackModel)
class FallbackModelTranslationOptions(TranslationOptions):
fields = ('title', 'text', 'url', 'email', 'description')
fields = ("title", "text", "url", "email", "description")
fallback_values = "fallback"
@register(models.FallbackModel2)
class FallbackModel2TranslationOptions(TranslationOptions):
fields = (
'title',
'text',
'url',
'email',
"title",
"text",
"url",
"email",
)
fallback_values = {'text': gettext_lazy('Sorry, translation is not available.')}
fallback_undefined = {'title': 'no title'}
fallback_values = {"text": gettext_lazy("Sorry, translation is not available.")}
fallback_undefined = {"title": "no title"}
# ######### File fields testing
@ -64,10 +64,10 @@ class FallbackModel2TranslationOptions(TranslationOptions):
@register(models.FileFieldsModel)
class FileFieldsModelTranslationOptions(TranslationOptions):
fields = (
'title',
'file',
'file2',
'image',
"title",
"file",
"file2",
"image",
)
@ -77,32 +77,32 @@ class FileFieldsModelTranslationOptions(TranslationOptions):
@register(models.ForeignKeyModel)
class ForeignKeyModelTranslationOptions(TranslationOptions):
fields = (
'title',
'test',
'optional',
'hidden',
'non',
"title",
"test",
"optional",
"hidden",
"non",
)
@register(models.OneToOneFieldModel)
class OneToOneFieldModelTranslationOptions(TranslationOptions):
fields = (
'title',
'test',
'optional',
'non',
"title",
"test",
"optional",
"non",
)
@register(models.FilteredTestModel)
class FilteredTestModelTranslationOptions(TranslationOptions):
fields = ('title',)
fields = ("title",)
@register(models.ForeignKeyFilteredModel)
class ForeignKeyFilteredModelTranslationOptions(TranslationOptions):
fields = ('title',)
fields = ("title",)
@register(models.ManyToManyFieldModel)
@ -120,7 +120,7 @@ class ManyToManyFieldModelTranslationOptions(TranslationOptions):
@register(models.RegisteredThroughModel)
class RegisteredThroughModelTranslationOptions(TranslationOptions):
fields = ('title',)
fields = ("title",)
# ######### Custom fields testing
@ -129,21 +129,21 @@ class RegisteredThroughModelTranslationOptions(TranslationOptions):
@register(models.OtherFieldsModel)
class OtherFieldsModelTranslationOptions(TranslationOptions):
fields = (
'int',
'boolean',
'float',
'decimal',
'genericip',
'date',
'datetime',
'time',
'json',
"int",
"boolean",
"float",
"decimal",
"genericip",
"date",
"datetime",
"time",
"json",
)
@register(models.DescriptorModel)
class DescriptorModelTranslationOptions(TranslationOptions):
fields = ('trans',)
fields = ("trans",)
# ######### Multitable inheritance testing
@ -151,17 +151,17 @@ class DescriptorModelTranslationOptions(TranslationOptions):
@register(models.MultitableModelA)
class MultitableModelATranslationOptions(TranslationOptions):
fields = ('titlea',)
fields = ("titlea",)
@register(models.MultitableModelB)
class MultitableModelBTranslationOptions(TranslationOptions):
fields = ('titleb',)
fields = ("titleb",)
@register(models.MultitableModelC)
class MultitableModelCTranslationOptions(TranslationOptions):
fields = ('titlec',)
fields = ("titlec",)
# ######### Abstract inheritance testing
@ -169,31 +169,31 @@ class MultitableModelCTranslationOptions(TranslationOptions):
@register(models.AbstractModelA)
class AbstractModelATranslationOptions(TranslationOptions):
fields = ('titlea',)
fields = ("titlea",)
@register(models.AbstractModelB)
class AbstractModelBTranslationOptions(TranslationOptions):
fields = ('titleb',)
fields = ("titleb",)
# ######### Fields inheritance testing
class SluggedTranslationOptions(TranslationOptions):
fields = ('slug',)
fields = ("slug",)
class MetaDataTranslationOptions(TranslationOptions):
fields = ('keywords',)
fields = ("keywords",)
class RichTextTranslationOptions(TranslationOptions):
fields = ('content',)
fields = ("content",)
class PageTranslationOptions(TranslationOptions):
fields = ('title',)
fields = ("title",)
# BasePage left unregistered intentionally.
@ -210,7 +210,7 @@ translator.register(models.RichTextPage)
@register(models.ManagerTestModel)
class ManagerTestModelTranslationOptions(TranslationOptions):
fields = ('title', 'visits', 'description')
fields = ("title", "visits", "description")
@register(
@ -222,32 +222,32 @@ class ManagerTestModelTranslationOptions(TranslationOptions):
]
)
class CustomManagerTestModelTranslationOptions(TranslationOptions):
fields = ('title',)
fields = ("title",)
# ######### TranslationOptions field inheritance testing
class FieldInheritanceATranslationOptions(TranslationOptions):
fields = ['titlea']
fields = ["titlea"]
class FieldInheritanceBTranslationOptions(FieldInheritanceATranslationOptions):
fields = ['titleb']
fields = ["titleb"]
class FieldInheritanceCTranslationOptions(FieldInheritanceBTranslationOptions):
fields = ['titlec']
fields = ["titlec"]
class FieldInheritanceDTranslationOptions(FieldInheritanceBTranslationOptions):
fields = ('titled',)
fields = ("titled",)
class FieldInheritanceETranslationOptions(
FieldInheritanceCTranslationOptions, FieldInheritanceDTranslationOptions
):
fields = ('titlee',)
fields = ("titlee",)
# ######### Integration testing
@ -255,7 +255,7 @@ class FieldInheritanceETranslationOptions(
@register(models.ThirdPartyRegisteredModel)
class ThirdPartyTranslationOptions(TranslationOptions):
fields = ('name',)
fields = ("name",)
# ######### Admin testing
@ -264,14 +264,14 @@ class ThirdPartyTranslationOptions(TranslationOptions):
@register(models.GroupFieldsetsModel)
class GroupFieldsetsTranslationOptions(TranslationOptions):
fields = (
'title',
'text',
"title",
"text",
)
@register(models.NameModel)
class NameTranslationOptions(TranslationOptions):
fields = ('firstname', 'lastname', 'slug2')
fields = ("firstname", "lastname", "slug2")
# ######### Required fields testing
@ -279,13 +279,13 @@ class NameTranslationOptions(TranslationOptions):
@register(models.RequiredModel)
class RequiredTranslationOptions(TranslationOptions):
fields = ('non_req', 'req', 'req_reg', 'req_en_reg')
fields = ("non_req", "req", "req_reg", "req_en_reg")
required_languages = {
'en': (
'req_reg',
'req_en_reg',
"en": (
"req_reg",
"req_en_reg",
),
'default': ('req_reg',), # for all other languages
"default": ("req_reg",), # for all other languages
}
@ -294,12 +294,12 @@ class RequiredTranslationOptions(TranslationOptions):
@register(models.ModelX)
class ModelXOptions(TranslationOptions):
fields = ('name',)
fields = ("name",)
@register(models.ModelY)
class ModelYOptions(TranslationOptions):
fields = ('title',)
fields = ("title",)
# ######### 3-rd party with custom manager
@ -307,10 +307,10 @@ class ModelYOptions(TranslationOptions):
@register(Group)
class GroupTranslationOptions(TranslationOptions):
fields = ('name',)
fields = ("name",)
@register(InheritedPermission)
class InheritedPermissionOptions(TranslationOptions):
fields = ('translated_var',)
fields = ("translated_var",)
required_languages = [x[0] for x in settings.LANGUAGES]

View file

@ -45,11 +45,11 @@ class FieldsAggregationMetaClass(type):
"""
def __new__(cls, name, bases, attrs):
attrs['fields'] = set(attrs.get('fields', ()))
attrs["fields"] = set(attrs.get("fields", ()))
for base in bases:
if isinstance(base, FieldsAggregationMetaClass):
attrs['fields'].update(base.fields)
attrs['fields'] = tuple(attrs['fields'])
attrs["fields"].update(base.fields)
attrs["fields"] = tuple(attrs["fields"])
return super().__new__(cls, name, bases, attrs)
@ -97,18 +97,18 @@ class TranslationOptions(metaclass=FieldsAggregationMetaClass):
if isinstance(self.required_languages, (tuple, list)):
self._check_languages(self.required_languages)
else:
self._check_languages(self.required_languages.keys(), extra=('default',))
self._check_languages(self.required_languages.keys(), extra=("default",))
for fieldnames in self.required_languages.values():
if any(f not in self.fields for f in fieldnames):
raise ImproperlyConfigured(
'Fieldname in required_languages which is not in fields option.'
"Fieldname in required_languages which is not in fields option."
)
def _check_languages(self, languages, extra=()):
correct = list(mt_settings.AVAILABLE_LANGUAGES) + list(extra)
if any(lang not in correct for lang in languages):
raise ImproperlyConfigured(
'Language in required_languages which is not in AVAILABLE_LANGUAGES.'
"Language in required_languages which is not in AVAILABLE_LANGUAGES."
)
def update(self, other):
@ -135,7 +135,7 @@ class TranslationOptions(metaclass=FieldsAggregationMetaClass):
def __str__(self):
local = tuple(self.local_fields.keys())
inherited = tuple(set(self.fields.keys()) - set(local))
return '%s: %s + %s' % (self.__class__.__name__, local, inherited)
return "%s: %s + %s" % (self.__class__.__name__, local, inherited)
class MultilingualOptions(options.Options):
@ -153,7 +153,7 @@ def add_translation_fields(model, opts):
Adds newly created translation fields to the given translation options.
"""
model_empty_values = getattr(opts, 'empty_values', NONE)
model_empty_values = getattr(opts, "empty_values", NONE)
for field_name in opts.local_fields.keys():
field_empty_value = parse_field(model_empty_values, field_name, NONE)
for lang in mt_settings.AVAILABLE_LANGUAGES:
@ -168,7 +168,7 @@ def add_translation_fields(model, opts):
if hasattr(model, localized_field_name):
# Check if are not dealing with abstract field inherited.
for cls in model.__mro__:
if hasattr(cls, '_meta') and cls.__dict__.get(localized_field_name, None):
if hasattr(cls, "_meta") and cls.__dict__.get(localized_field_name, None):
cls_opts = translator._get_options_for_model(cls)
if not cls._meta.abstract or field_name not in cls_opts.local_fields:
raise ValueError(
@ -204,7 +204,7 @@ def patch_manager_class(manager):
def deconstruct(self):
return (
False, # as_manager
'%s.%s' % (self._old_module, self._old_class), # manager_class
"%s.%s" % (self._old_module, self._old_class), # manager_class
None, # qs_class
self._constructor_args[0], # args
self._constructor_args[1], # kwargs
@ -281,7 +281,7 @@ def patch_constructor(model):
def delete_mt_init(sender, instance, **kwargs):
if hasattr(instance, '_mt_init'):
if hasattr(instance, "_mt_init"):
del instance._mt_init
@ -292,7 +292,7 @@ def patch_clean_fields(model):
old_clean_fields = model.clean_fields
def new_clean_fields(self, exclude=None):
if hasattr(self, '_mt_form_pending_clear'):
if hasattr(self, "_mt_form_pending_clear"):
# Some form translation fields has been marked as clearing value.
# Check if corresponding translated field was also saved (not excluded):
# - if yes, it seems like form for MT-unaware app. Ignore clearing (left value from
@ -303,12 +303,12 @@ def patch_clean_fields(model):
orig_field_name = field.translated_field.name
if orig_field_name in exclude:
field.save_form_data(self, value, check=False)
delattr(self, '_mt_form_pending_clear')
delattr(self, "_mt_form_pending_clear")
try:
setattr(self, '_mt_disable', True)
setattr(self, "_mt_disable", True)
old_clean_fields(self, exclude)
finally:
setattr(self, '_mt_disable', False)
setattr(self, "_mt_disable", False)
model.clean_fields = new_clean_fields
@ -317,13 +317,13 @@ def patch_get_deferred_fields(model):
"""
Django >= 1.8: patch detecting deferred fields. Crucial for only/defer to work.
"""
if not hasattr(model, 'get_deferred_fields'):
if not hasattr(model, "get_deferred_fields"):
return
old_get_deferred_fields = model.get_deferred_fields
def new_get_deferred_fields(self):
sup = old_get_deferred_fields(self)
if hasattr(self, '_fields_were_deferred'):
if hasattr(self, "_fields_were_deferred"):
sup.update(self._fields_were_deferred)
return sup
@ -334,7 +334,7 @@ def patch_refresh_from_db(model):
"""
Django >= 1.10: patch refreshing deferred fields. Crucial for only/defer to work.
"""
if not hasattr(model, 'refresh_from_db'):
if not hasattr(model, "refresh_from_db"):
return
old_refresh_from_db = model.refresh_from_db
@ -349,12 +349,12 @@ def patch_refresh_from_db(model):
def delete_cache_fields(model):
opts = model._meta
cached_attrs = (
'_field_cache',
'_field_name_cache',
'_name_map',
'fields',
'concrete_fields',
'local_concrete_fields',
"_field_cache",
"_field_name_cache",
"_name_map",
"fields",
"concrete_fields",
"local_concrete_fields",
)
for attr in cached_attrs:
try:
@ -362,7 +362,7 @@ def delete_cache_fields(model):
except AttributeError:
pass
if hasattr(model._meta, '_expire_cache'):
if hasattr(model._meta, "_expire_cache"):
model._meta._expire_cache()
@ -396,19 +396,19 @@ def populate_translation_fields(sender, kwargs):
return
if populate is True:
# What was meant by ``True`` is now called ``all``.
populate = 'all'
populate = "all"
opts = translator.get_options_for_model(sender)
for key, val in list(kwargs.items()):
if key in opts.fields:
if populate == 'all':
if populate == "all":
# Set the value for every language.
for translation_field in opts.fields[key]:
kwargs.setdefault(translation_field.name, val)
elif populate == 'default':
elif populate == "default":
default = build_localized_fieldname(key, mt_settings.DEFAULT_LANGUAGE)
kwargs.setdefault(default, val)
elif populate == 'required':
elif populate == "required":
default = build_localized_fieldname(key, mt_settings.DEFAULT_LANGUAGE)
if not sender._meta.get_field(key).null:
kwargs.setdefault(default, val)
@ -532,9 +532,9 @@ class Translator:
patch_refresh_from_db(model)
# Substitute original field with descriptor
model_fallback_languages = getattr(opts, 'fallback_languages', None)
model_fallback_values = getattr(opts, 'fallback_values', NONE)
model_fallback_undefined = getattr(opts, 'fallback_undefined', NONE)
model_fallback_languages = getattr(opts, "fallback_languages", None)
model_fallback_values = getattr(opts, "fallback_values", NONE)
model_fallback_undefined = getattr(opts, "fallback_undefined", NONE)
for field_name in opts.local_fields.keys():
field = model._meta.get_field(field_name)
field_fallback_value = parse_field(model_fallback_values, field_name, NONE)
@ -628,7 +628,7 @@ class Translator:
# Fields for translation may be inherited from abstract
# superclasses, so we need to look at all parents.
for base in model.__bases__:
if not hasattr(base, '_meta'):
if not hasattr(base, "_meta"):
# Things without _meta aren't functional models, so they're
# uninteresting parents.
continue
@ -648,7 +648,7 @@ class Translator:
opts = self._get_options_for_model(model)
if not opts.registered and not opts.related:
raise NotRegistered(
'The model "%s" is not registered for ' 'translation' % model.__name__
'The model "%s" is not registered for ' "translation" % model.__name__
)
return opts

View file

@ -22,8 +22,8 @@ def get_language():
lang = _get_language()
if lang is None: # Django >= 1.8
return settings.DEFAULT_LANGUAGE
if lang not in settings.AVAILABLE_LANGUAGES and '-' in lang:
lang = lang.split('-')[0]
if lang not in settings.AVAILABLE_LANGUAGES and "-" in lang:
lang = lang.split("-")[0]
if lang in settings.AVAILABLE_LANGUAGES:
return lang
return settings.DEFAULT_LANGUAGE
@ -34,7 +34,7 @@ def get_language_bidi(lang):
Check if a language is bi-directional.
"""
lang_info = get_language_info(lang)
return lang_info['bidi']
return lang_info["bidi"]
def get_translation_fields(field):
@ -45,37 +45,37 @@ def get_translation_fields(field):
def build_localized_fieldname(field_name, lang):
if lang == 'id':
if lang == "id":
# The 2-letter Indonesian language code is problematic with the
# current naming scheme as Django foreign keys also add "id" suffix.
lang = 'ind'
return str('%s_%s' % (field_name, lang.replace('-', '_')))
lang = "ind"
return str("%s_%s" % (field_name, lang.replace("-", "_")))
def _build_localized_verbose_name(verbose_name, lang):
if lang == 'id':
lang = 'ind'
return force_str('%s [%s]') % (force_str(verbose_name), lang)
if lang == "id":
lang = "ind"
return force_str("%s [%s]") % (force_str(verbose_name), lang)
build_localized_verbose_name = lazy(_build_localized_verbose_name, str)
def _join_css_class(bits, offset):
if '-'.join(bits[-offset:]) in settings.AVAILABLE_LANGUAGES + ['en-us']:
return '%s-%s' % ('_'.join(bits[: len(bits) - offset]), '_'.join(bits[-offset:]))
return ''
if "-".join(bits[-offset:]) in settings.AVAILABLE_LANGUAGES + ["en-us"]:
return "%s-%s" % ("_".join(bits[: len(bits) - offset]), "_".join(bits[-offset:]))
return ""
def build_css_class(localized_fieldname, prefix=''):
def build_css_class(localized_fieldname, prefix=""):
"""
Returns a css class based on ``localized_fieldname`` which is easily
splittable and capable of regionalized language codes.
Takes an optional ``prefix`` which is prepended to the returned string.
"""
bits = localized_fieldname.split('_')
css_class = ''
bits = localized_fieldname.split("_")
css_class = ""
if len(bits) == 1:
css_class = str(localized_fieldname)
elif len(bits) == 2:
@ -83,7 +83,7 @@ def build_css_class(localized_fieldname, prefix=''):
# Examples:
# 'foo_de' --> 'foo-de',
# 'bar_en' --> 'bar-en'
css_class = '-'.join(bits)
css_class = "-".join(bits)
elif len(bits) > 2:
# Try regionalized language code
# Examples:
@ -96,7 +96,7 @@ def build_css_class(localized_fieldname, prefix=''):
# 'foo_bar_de' --> 'foo_bar-de',
# 'foo_bar_baz_de' --> 'foo_bar_baz-de'
css_class = _join_css_class(bits, 1)
return '%s-%s' % (prefix, css_class) if prefix else css_class
return "%s-%s" % (prefix, css_class) if prefix else css_class
def unique(seq):
@ -124,13 +124,13 @@ def resolution_order(lang, override=None):
if override is None:
override = {}
fallback_for_lang = override.get(lang, settings.FALLBACK_LANGUAGES.get(lang, ()))
fallback_def = override.get('default', settings.FALLBACK_LANGUAGES['default'])
fallback_def = override.get("default", settings.FALLBACK_LANGUAGES["default"])
order = (lang,) + fallback_for_lang + fallback_def
return tuple(unique(order))
@contextmanager
def auto_populate(mode='all'):
def auto_populate(mode="all"):
"""
Overrides translation fields population mode (population mode decides which
unprovided translations will be filled during model construction / loading).

View file

@ -28,7 +28,7 @@ class ClearableWidgetWrapper(Widget):
# template = '<span class="clearable-input">{} <label for="{}">{}</label> {}</span>'
class Media:
js = ('modeltranslation/js/clearable_inputs.js',)
js = ("modeltranslation/js/clearable_inputs.js",)
def __init__(self, widget, empty_value=None):
"""
@ -36,7 +36,7 @@ class ClearableWidgetWrapper(Widget):
Allows overriding the empty value.
"""
self.widget = widget
self.checkbox = CheckboxInput(attrs={'tabindex': '-1'})
self.checkbox = CheckboxInput(attrs={"tabindex": "-1"})
self.empty_value = empty_value
def __getattr__(self, name):
@ -44,7 +44,7 @@ class ClearableWidgetWrapper(Widget):
If we don't have a property or a method, chances are the wrapped
widget does.
"""
if name != 'widget':
if name != "widget":
return getattr(self.widget, name)
raise AttributeError
@ -66,7 +66,7 @@ class ClearableWidgetWrapper(Widget):
checkbox_id = self.clear_checkbox_id(checkbox_name)
checkbox_label = self.clear_checkbox_label
checkbox = self.checkbox.render(
checkbox_name, value == self.empty_value, attrs={'id': checkbox_id}, renderer=renderer
checkbox_name, value == self.empty_value, attrs={"id": checkbox_id}, renderer=renderer
)
return mark_safe(
self.template.format(
@ -91,10 +91,10 @@ class ClearableWidgetWrapper(Widget):
"""
Given the name of the input, returns the name of the clear checkbox.
"""
return name + '-clear'
return name + "-clear"
def clear_checkbox_id(self, name):
"""
Given the name of the clear checkbox input, returns the HTML id for it.
"""
return name + '_id'
return name + "_id"