Exemplo n.º 1
0
    def _patch_panel(model, panel):
        """
        Generic panel patching function
        """

        WagtailTranslator._current_model = model
        WagtailTranslator._translation_options = translator.get_options_for_model(
            model)
        if model not in WagtailTranslator._required_fields:
            WagtailTranslator._required_fields[model] = []

        if panel.__class__.__name__ == 'FieldPanel':
            trpanels = WagtailTranslator._patch_fieldpanel(panel)
        elif panel.__class__.__name__ == 'ImageChooserPanel':
            trpanels = WagtailTranslator._patch_imagechooser(panel)
        elif panel.__class__.__name__ == 'MultiFieldPanel':
            trpanels = [WagtailTranslator._patch_multifieldpanel(panel)]
        elif panel.__class__.__name__ == 'InlinePanel':
            WagtailTranslator._patch_inlinepanel(model, panel)
            trpanels = [panel]
        elif panel.__class__.__name__ == 'StreamFieldPanel':
            trpanels = WagtailTranslator._patch_streamfieldpanel(panel)
        elif panel.__class__.__name__ == 'FieldRowPanel':
            trpanels = [WagtailTranslator._patch_fieldrowpanel(panel)]
        else:
            trpanels = [panel]

        return trpanels
Exemplo n.º 2
0
    def _patch_inlinepanel(cls, instance, panel):
        relation = getattr(instance.__class__, panel.relation_name)

        related_fieldname = 'related'

        try:
            inline_panels = getattr(
                getattr(relation, related_fieldname).model, 'panels', [])
        except AttributeError:
            related_fieldname = 'rel'
            inline_panels = getattr(
                getattr(relation, related_fieldname).model, 'panels', [])

        try:
            model = getattr(getattr(instance.__class__, panel.relation_name),
                            related_fieldname).model
            inline_model_tr_fields = translator.get_options_for_model(
                model).fields
        except NotRegistered:
            return None

        translated_inline = []
        for inlinepanel in inline_panels:
            for item in cls._patch_fieldpanel(inlinepanel,
                                              inline_model_tr_fields):
                translated_inline.append(item)

        model.panels = translated_inline
    def _patch_panel(model, panel):
        """
        Generic panel patching function
        """

        WagtailTranslator._current_model = model
        WagtailTranslator._translation_options = translator.get_options_for_model(model)
        if model not in WagtailTranslator._required_fields:
            WagtailTranslator._required_fields[model] = []

        if panel.__class__.__name__ == 'FieldPanel':
            trpanels = WagtailTranslator._patch_fieldpanel(panel)
        elif panel.__class__.__name__ == 'ImageChooserPanel':
            trpanels = WagtailTranslator._patch_imagechooser(panel)
        elif panel.__class__.__name__ == 'MultiFieldPanel':
            trpanels = [WagtailTranslator._patch_multifieldpanel(panel)]
        elif panel.__class__.__name__ == 'InlinePanel':
            WagtailTranslator._patch_inlinepanel(model, panel)
            trpanels = [panel]
        elif panel.__class__.__name__ == 'StreamFieldPanel':
            trpanels = WagtailTranslator._patch_streamfieldpanel(panel)
        elif panel.__class__.__name__ == 'FieldRowPanel':
            trpanels = [WagtailTranslator._patch_fieldrowpanel(panel)]
        else:
            trpanels = [panel]

        return trpanels
Exemplo n.º 4
0
    def _patch_inlinepanel(cls, model, panel):
        relation = getattr(model, panel.relation_name)

        related_fieldname = 'related'

        try:
            inline_panels = getattr(
                getattr(relation, related_fieldname).related_model, 'panels',
                [])
        except AttributeError:
            related_fieldname = 'rel'
            inline_panels = getattr(
                getattr(relation, related_fieldname).related_model, 'panels',
                [])

        try:
            related_model = getattr(getattr(model, panel.relation_name),
                                    related_fieldname).related_model
            WagtailTranslator._translation_options = translator.get_options_for_model(
                related_model)
        except NotRegistered:
            return None
        translated_inline = []
        for inline_panel in inline_panels:
            for item in cls._patch_panel(related_model, inline_panel):
                translated_inline.append(item)

        related_model.panels = translated_inline
Exemplo n.º 5
0
    def handle_noargs(self, **options):
        verbosity = int(options['verbosity'])
        if verbosity > 0:
            self.stdout.write("Using default language: %s\n" %
                              DEFAULT_LANGUAGE)
        models = translator.get_registered_models(abstract=False)
        for model in models:
            if verbosity > 0:
                self.stdout.write("Updating data of model '%s'\n" % model)
            opts = translator.get_options_for_model(model)
            for field_name in opts.fields.keys():
                def_lang_fieldname = build_localized_fieldname(
                    field_name, DEFAULT_LANGUAGE)

                # We'll only update fields which do not have an existing value
                q = Q(**{def_lang_fieldname: None})
                field = model._meta.get_field(field_name)
                if field.empty_strings_allowed:
                    q |= Q(**{def_lang_fieldname: ''})

                if issubclass(model, Page):
                    for obj in model._default_manager.filter(q):
                        # Get table description in order to know if field is
                        # in child or parent table
                        # TODO: Tested only on PostgreSQL engine
                        db_table = model._meta.db_table
                        db_table_desc = connection.introspection.\
                            get_table_description(
                                connection.cursor(), db_table)
                        # original field in child class
                        if field_name in [x.name for x in db_table_desc]:
                            raw = model._default_manager.raw(
                                'SELECT *, %s AS original_field FROM %s \
                                 WHERE page_ptr_id=%d LIMIT 1' %
                                (field_name, db_table, obj.page_ptr_id))[0]
                            setattr(obj, def_lang_fieldname,
                                    raw.original_field)
                        # field is a foreign key
                        elif (field_name + '_id') in\
                                [x.name for x in db_table_desc]:
                            raw = model._default_manager.raw(
                                'SELECT *, %s AS original_field FROM %s \
                                 WHERE page_ptr_id=%d LIMIT 1' %
                                (field_name + '_id', db_table,
                                 obj.page_ptr_id))[0]
                            setattr(obj, def_lang_fieldname + '_id',
                                    raw.original_field)
                        # original field parent class
                        else:
                            raw = Page._default_manager.raw(
                                'SELECT *, %s AS original_field FROM \
                                 wagtailcore_page WHERE id=%d LIMIT 1' %
                                (field_name, obj.page_ptr_id))[0]
                            setattr(obj, def_lang_fieldname,
                                    raw.original_field)
                        obj.save(update_fields=[def_lang_fieldname])
                else:
                    model._default_manager.filter(q).rewrite(False).update(
                        **{def_lang_fieldname: F(field_name)})
Exemplo n.º 6
0
def append_translated(model, fields):
    "If translated field is encountered, add also all its translation fields."
    fields = set(fields)
    from wagtail_modeltranslation.translator import translator
    opts = translator.get_options_for_model(model)
    for key, translated in opts.fields.items():
        if key in fields:
            fields = fields.union(f.name for f in translated)
    return fields
    def handle_noargs(self, **options):
        verbosity = int(options['verbosity'])
        if verbosity > 0:
            self.stdout.write(
                "Using default language: %s\n" % DEFAULT_LANGUAGE)
        models = translator.get_registered_models(abstract=False)
        for model in models:
            if verbosity > 0:
                self.stdout.write("Updating data of model '%s'\n" % model)
            opts = translator.get_options_for_model(model)
            for field_name in opts.fields.keys():
                def_lang_fieldname = build_localized_fieldname(
                    field_name, DEFAULT_LANGUAGE)

                # We'll only update fields which do not have an existing value
                q = Q(**{def_lang_fieldname: None})
                field = model._meta.get_field(field_name)
                if field.empty_strings_allowed:
                    q |= Q(**{def_lang_fieldname: ''})

                if issubclass(model, Page):
                    for obj in model._default_manager.filter(q):
                        # Get table description in order to know if field is
                        # in child or parent table
                        # TODO: Tested only on PostgreSQL engine
                        db_table = model._meta.db_table
                        db_table_desc = connection.introspection.\
                            get_table_description(
                                connection.cursor(), db_table)
                        # original field in child class
                        if field_name in [x.name for x in db_table_desc]:
                            raw = model._default_manager.raw(
                                'SELECT *, %s AS original_field FROM %s \
                                 WHERE page_ptr_id=%d LIMIT 1' % (
                                    field_name, db_table, obj.page_ptr_id))[0]
                            setattr(
                                obj, def_lang_fieldname, raw.original_field)
                        # original field parent class
                        else:
                            raw = Page._default_manager.raw(
                                'SELECT *, %s AS original_field FROM \
                                 wagtailcore_page WHERE id=%d LIMIT 1' % (
                                    field_name, obj.page_ptr_id))[0]
                            setattr(
                                obj, def_lang_fieldname, raw.original_field)
                        obj.save(update_fields=[def_lang_fieldname])
                else:
                    model._default_manager.filter(q).rewrite(False).update(
                        **{def_lang_fieldname: F(field_name)})
Exemplo n.º 8
0
    def _patch_inlinepanel(cls, instance, panel):
        relation = getattr(instance.__class__, panel.relation_name)
        inline_panels = getattr(relation.related.model, 'panels', [])
        try:
            inline_model_tr_fields = translator.get_options_for_model(
                getattr(
                    instance.__class__, panel.relation_name).related.model).fields
        except NotRegistered:
            return None

        translated_inline = []
        for inlinepanel in inline_panels:
            for item in cls._patch_fieldpanel(inlinepanel, inline_model_tr_fields):
                translated_inline.append(item)

        getattr(instance.__class__, panel.relation_name).related.model.panels = translated_inline
Exemplo n.º 9
0
def append_fallback(model, fields):
    """
    If translated field is encountered, add also all its fallback fields.
    Returns tuple: (set_of_new_fields_to_use, set_of_translated_field_names)
    """
    fields = set(fields)
    trans = set()
    from wagtail_modeltranslation.translator import translator
    opts = translator.get_options_for_model(model)
    for key, _ in opts.fields.items():
        if key in fields:
            langs = resolution_order(get_language(), getattr(model, key).fallback_languages)
            fields = fields.union(build_localized_fieldname(key, lang) for lang in langs)
            fields.remove(key)
            trans.add(key)
    return fields, trans
Exemplo n.º 10
0
    def handle_noargs(self, **options):
        """
        Command execution.
        """
        self.cursor = connection.cursor()
        self.introspection = connection.introspection
        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
            if django.VERSION < (1, 8):
                model_name = model._meta.module_name
            else:
                model_name = model._meta.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
                field = list(fields)[0]
                column_name = field.db_column if field.db_column else field_name
                missing_langs = list(
                    self.get_missing_languages(column_name, db_table))
                if missing_langs:
                    found_missing_fields = True
                    print_missing_langs(missing_langs, field_name,
                                        model_full_name)
                    sql_sentences = self.get_sync_sql(field_name,
                                                      missing_langs, model)
                    execute_sql = ask_for_confirmation(sql_sentences,
                                                       model_full_name,
                                                       self.interactive)
                    if execute_sql:
                        print('Executing SQL...')
                        for sentence in sql_sentences:
                            self.cursor.execute(sentence)
                        print('Done')
                    else:
                        print('SQL not executed')

        if django.VERSION < (1, 6):
            transaction.commit_unless_managed()

        if not found_missing_fields:
            print('No new translatable fields detected')
    def _patch_inlinepanel(cls, instance, panel):
        relation = getattr(instance.__class__, panel.relation_name)
        inline_panels = getattr(relation.related.model, 'panels', [])
        try:
            inline_model_tr_fields = translator.get_options_for_model(
                getattr(instance.__class__,
                        panel.relation_name).related.model).fields
        except NotRegistered:
            return None

        translated_inline = []
        for inlinepanel in inline_panels:
            for item in cls._patch_fieldpanel(inlinepanel,
                                              inline_model_tr_fields):
                translated_inline.append(item)

        getattr(instance.__class__, panel.relation_name).related.model.panels =\
            translated_inline
    def handle_noargs(self, **options):
        """
        Command execution.
        """
        self.cursor = connection.cursor()
        self.introspection = connection.introspection
        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
            if django.VERSION < (1, 8):
                model_name = model._meta.module_name
            else:
                model_name = model._meta.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
                field = list(fields)[0]
                column_name = field.db_column if field.db_column else field_name
                missing_langs = list(self.get_missing_languages(column_name, db_table))
                if missing_langs:
                    found_missing_fields = True
                    print_missing_langs(missing_langs, field_name, model_full_name)
                    sql_sentences = self.get_sync_sql(field_name, missing_langs, model)
                    execute_sql = ask_for_confirmation(
                        sql_sentences, model_full_name, self.interactive)
                    if execute_sql:
                        print('Executing SQL...')
                        for sentence in sql_sentences:
                            self.cursor.execute(sentence)
                        print('Done')
                    else:
                        print('SQL not executed')

        if django.VERSION < (1, 6):
            transaction.commit_unless_managed()

        if not found_missing_fields:
            print('No new translatable fields detected')
    def handle_noargs(self, **options):
        verbosity = int(options['verbosity'])
        if verbosity > 0:
            self.stdout.write("Using default language: %s\n" % DEFAULT_LANGUAGE)
        models = translator.get_registered_models(abstract=False)
        for model in models:
            if verbosity > 0:
                self.stdout.write("Updating data of model '%s'\n" % model)
            opts = translator.get_options_for_model(model)
            for field_name in opts.fields.keys():
                def_lang_fieldname = build_localized_fieldname(field_name, DEFAULT_LANGUAGE)

                # We'll only update fields which do not have an existing value
                q = Q(**{def_lang_fieldname: None})
                field = model._meta.get_field(field_name)
                if field.empty_strings_allowed:
                    q |= Q(**{def_lang_fieldname: ""})

                model._default_manager.filter(q).rewrite(False).update(
                    **{def_lang_fieldname: F(field_name)})
    def _patch_inlinepanel(cls, model, panel):
        relation = getattr(model, panel.relation_name)

        related_fieldname = 'related'

        try:
            inline_panels = getattr(getattr(relation, related_fieldname).related_model, 'panels', [])
        except AttributeError:
            related_fieldname = 'rel'
            inline_panels = getattr(getattr(relation, related_fieldname).related_model, 'panels', [])

        try:
            related_model = getattr(getattr(model, panel.relation_name), related_fieldname).related_model
            WagtailTranslator._translation_options = translator.get_options_for_model(related_model)
        except NotRegistered:
            return None
        translated_inline = []
        for inline_panel in inline_panels:
            for item in cls._patch_panel(related_model, inline_panel):
                translated_inline.append(item)

        related_model.panels = translated_inline
    def handle_noargs(self, **options):
        verbosity = int(options['verbosity'])
        if verbosity > 0:
            self.stdout.write("Using default language: %s\n" %
                              DEFAULT_LANGUAGE)
        models = translator.get_registered_models(abstract=False)
        for model in models:
            if verbosity > 0:
                self.stdout.write("Updating data of model '%s'\n" % model)
            opts = translator.get_options_for_model(model)
            for field_name in opts.fields.keys():
                def_lang_fieldname = build_localized_fieldname(
                    field_name, DEFAULT_LANGUAGE)

                # We'll only update fields which do not have an existing value
                q = Q(**{def_lang_fieldname: None})
                field = model._meta.get_field(field_name)
                if field.empty_strings_allowed:
                    q |= Q(**{def_lang_fieldname: ""})

                model._default_manager.filter(q).rewrite(False).update(
                    **{def_lang_fieldname: F(field_name)})
Exemplo n.º 16
0
    def __init__(self, translated_field, language, empty_value, *args, **kwargs):
        from wagtail_modeltranslation.translator import translator

        # Update the dict of this field with the content of the original one
        # This might be a bit radical?! Seems to work though...
        self.__dict__.update(translated_field.__dict__)

        # Store the originally wrapped field for later
        self.translated_field = translated_field
        self.language = language
        self.empty_value = empty_value
        if empty_value is NONE:
            self.empty_value = None if translated_field.null else ''

        # Default behaviour is that all translations are optional
        if not isinstance(self, fields.BooleanField):
            # TODO: Do we really want to enforce null *at all*? Shouldn't this
            # better honour the null setting of the translated field?
            self.null = True
        self.blank = True

        # Take required_languages translation option into account
        trans_opts = translator.get_options_for_model(self.model)
        if trans_opts.required_languages:
            required_languages = trans_opts.required_languages
            if isinstance(trans_opts.required_languages, (tuple, list)):
                # All fields
                if self.language in required_languages:
                    # self.null = False
                    self.blank = False
            else:
                # Certain fields only
                # Try current language - if not present, try 'default' key
                try:
                    req_fields = required_languages[self.language]
                except KeyError:
                    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.
                    # self.null = False
                    self.blank = False

        # Adjust the name of this field to reflect the language
        self.attname = build_localized_fieldname(self.translated_field.name, language)
        self.name = self.attname
        if self.translated_field.db_column:
            self.db_column = build_localized_fieldname(self.translated_field.db_column, language)
            self.column = self.db_column

        # Copy the verbose name and append a language suffix
        # (will show up e.g. in the admin).
        self.verbose_name = build_localized_verbose_name(translated_field.verbose_name, language)

        # ForeignKey support - rewrite related_name
        if not NEW_RELATED_API and self.rel and self.related and not self.rel.is_hidden():
            import copy
            current = self.related.get_accessor_name()
            self.rel = copy.copy(self.rel)  # Since fields cannot share the same rel object.
            # self.related doesn't need to be copied, as it will be recreated in
            # ``RelatedField.do_related_class``

            if self.rel.related_name is None:
                # For implicit related_name use different query field name
                loc_related_query_name = build_localized_fieldname(
                    self.related_query_name(), self.language)
                self.related_query_name = lambda: loc_related_query_name
            self.rel.related_name = build_localized_fieldname(current, self.language)
            self.rel.field = self  # Django 1.6
            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():
            import copy
            current = self.remote_field.get_accessor_name()
            # Since fields cannot share the same rel object:
            self.remote_field = copy.copy(self.remote_field)

            if self.remote_field.related_name is None:
                # For implicit related_name use different query field name
                loc_related_query_name = build_localized_fieldname(
                    self.related_query_name(), self.language)
                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  # Django 1.6
            if hasattr(self.remote_field.to._meta, '_related_objects_cache'):
                del self.remote_field.to._meta._related_objects_cache
Exemplo n.º 17
0
def get_translatable_fields_for_model(model):
    from wagtail_modeltranslation.translator import NotRegistered, translator
    try:
        return translator.get_options_for_model(model).get_field_names()
    except NotRegistered:
        return None
    def __init__(self, translated_field, language, empty_value, *args,
                 **kwargs):
        from wagtail_modeltranslation.translator import translator

        # Update the dict of this field with the content of the original one
        # This might be a bit radical?! Seems to work though...
        self.__dict__.update(translated_field.__dict__)

        # Store the originally wrapped field for later
        self.translated_field = translated_field
        self.language = language
        self.empty_value = empty_value
        if empty_value is NONE:
            self.empty_value = None if translated_field.null else ''

        # Default behaviour is that all translations are optional
        if not isinstance(self, fields.BooleanField):
            # TODO: Do we really want to enforce null *at all*? Shouldn't this
            # better honour the null setting of the translated field?
            self.null = True
        self.blank = True

        # Take required_languages translation option into account
        trans_opts = translator.get_options_for_model(self.model)
        if trans_opts.required_languages:
            required_languages = trans_opts.required_languages
            if isinstance(trans_opts.required_languages, (tuple, list)):
                # All fields
                if self.language in required_languages:
                    # self.null = False
                    self.blank = False
            else:
                # Certain fields only
                # Try current language - if not present, try 'default' key
                try:
                    req_fields = required_languages[self.language]
                except KeyError:
                    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.
                    # self.null = False
                    self.blank = False

        # Adjust the name of this field to reflect the language
        self.attname = build_localized_fieldname(self.translated_field.name,
                                                 language)
        self.name = self.attname
        if self.translated_field.db_column:
            self.db_column = build_localized_fieldname(
                self.translated_field.db_column, language)
            self.column = self.db_column

        # Copy the verbose name and append a language suffix
        # (will show up e.g. in the admin).
        self.verbose_name = build_localized_verbose_name(
            translated_field.verbose_name, language)

        # ForeignKey support - rewrite related_name
        if not NEW_RELATED_API and self.rel and self.related and not self.rel.is_hidden(
        ):
            import copy
            current = self.related.get_accessor_name()
            self.rel = copy.copy(
                self.rel)  # Since fields cannot share the same rel object.
            # self.related doesn't need to be copied, as it will be recreated in
            # ``RelatedField.do_related_class``

            if self.rel.related_name is None:
                # For implicit related_name use different query field name
                loc_related_query_name = build_localized_fieldname(
                    self.related_query_name(), self.language)
                self.related_query_name = lambda: loc_related_query_name
            self.rel.related_name = build_localized_fieldname(
                current, self.language)
            self.rel.field = self  # Django 1.6
            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(
        ):
            import copy
            current = self.remote_field.get_accessor_name()
            # Since fields cannot share the same rel object:
            self.remote_field = copy.copy(self.remote_field)

            if self.remote_field.related_name is None:
                # For implicit related_name use different query field name
                loc_related_query_name = build_localized_fieldname(
                    self.related_query_name(), self.language)
                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  # Django 1.6
            if hasattr(self.remote_field.to._meta, '_related_objects_cache'):
                del self.remote_field.to._meta._related_objects_cache