def test_get_language_title(self):
        """Test get_language_title utility function"""
        language_code = "en"
        self.assertEqual(get_language_title(language_code), "English")

        # Test the case where requested language is not in settings.
        # We can not override settings, since languages in get_language_title()
        # are initialised during import. So, we use fictional language code.
        language_code = "xx"
        try:
            self.assertEqual(get_language_title(language_code), language_code)
        except KeyError:
            self.fail("get_language_title() raises KeyError for missing language")
Example #2
0
    def test_get_language_title(self):
        """Test get_language_title utility function"""
        language_code = 'en'
        self.assertEqual(get_language_title(language_code), 'English')

        # Test the case where requested language is not in settings.
        # We can not override settings, since languages in get_language_title()
        # are initialised during import. So, we use fictional language code.
        language_code = 'xx'
        try:
            self.assertEqual(get_language_title(language_code), language_code)
        except KeyError:
            self.fail(
                "get_language_title() raises KeyError for missing language")
Example #3
0
    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
        """
        Insert the language tabs.
        """
        if self._has_translatable_model():
            lang_code = self.get_form_language(request, obj)
            lang = get_language_title(lang_code)

            available_languages = self.get_available_languages(obj)
            language_tabs = self.get_language_tabs(request, obj, available_languages)
            context['language_tabs'] = language_tabs
            if language_tabs:
                context['title'] = '%s (%s)' % (context['title'], lang)
            if not language_tabs.current_is_translated:
                add = True  # lets prepopulated_fields_js work.

            # Patch form_url to contain the "language" GET parameter.
            # Otherwise AdminModel.render_change_form will clean the URL
            # and remove the "language" when coming from a filtered object
            # list causing the wrong translation to be changed.

            params = request.GET.dict()
            params['language'] = lang_code
            form_url = add_preserved_filters({
                'preserved_filters': urlencode(params),
                'opts': self.model._meta
            }, form_url)

        # django-fluent-pages uses the same technique
        if 'default_change_form_template' not in context:
            context['default_change_form_template'] = self.get_change_form_base_template()

        #context['base_template'] = self.get_change_form_base_template()
        return super(TranslatableAdmin, self).render_change_form(request, context, add, change, form_url, obj)
Example #4
0
    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
        """
        Insert the language tabs.
        """
        if self._has_translatable_model():
            lang_code = self.get_form_language(request, obj)
            lang = get_language_title(lang_code)

            available_languages = self.get_available_languages(obj)
            current_is_translated = lang_code in available_languages
            language_tabs = self.get_language_tabs(request, obj, available_languages)

            context['current_is_translated'] = current_is_translated
            context['allow_deletion'] = len(available_languages) > 1
            context['language_tabs'] = language_tabs
            if language_tabs:
                context['title'] = '%s (%s)' % (context['title'], lang)
            if not current_is_translated:
                add = True  # lets prepopulated_fields_js work.

        # django-fluent-pages uses the same technique
        if 'default_change_form_template' not in context:
            context['default_change_form_template'] = self.get_change_form_base_template()

        #context['base_template'] = self.get_change_form_base_template()
        return super(TranslatableAdmin, self).render_change_form(request, context, add, change, form_url, obj)
Example #5
0
    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
        """
        Insert the language tabs.
        """
        if self._has_translatable_model():
            lang_code = self.get_form_language(request, obj)
            lang = get_language_title(lang_code)

            available_languages = self.get_available_languages(obj)
            language_tabs = self.get_language_tabs(request, obj, available_languages)
            context['language_tabs'] = language_tabs
            if language_tabs:
                context['title'] = '%s (%s)' % (context['title'], lang)
            if not language_tabs.current_is_translated:
                add = True  # lets prepopulated_fields_js work.

            # Patch form_url to contain the "language" GET parameter.
            # Otherwise AdminModel.render_change_form will clean the URL
            # and remove the "language" when coming from a filtered object
            # list causing the wrong translation to be changed.

            params = request.GET.dict()
            params['language'] = lang_code
            form_url = add_preserved_filters({
                'preserved_filters': urlencode(params),
                'opts': self.model._meta
            }, form_url)

        # django-fluent-pages uses the same technique
        if 'default_change_form_template' not in context:
            context['default_change_form_template'] = self.default_change_form_template

        #context['base_template'] = self.get_change_form_base_template()
        return super(TranslatableAdmin, self).render_change_form(request, context, add, change, form_url, obj)
Example #6
0
    def get_language_tabs(self, request, obj, available_languages):
        """
        Determine the language tabs to show.
        """
        tabs = []
        get = request.GET.copy()  # QueryDict object
        language = self.get_form_language(request, obj)
        tab_languages = []

        base_url = '{0}://{1}{2}'.format(
            request.is_secure() and 'https' or 'http', request.get_host(),
            request.path)

        for lang_dict in appsettings.PARLER_LANGUAGES.get(
                settings.SITE_ID, ()):
            code = lang_dict['code']
            title = get_language_title(code)
            get['language'] = code
            url = '{0}?{1}'.format(base_url, get.urlencode())

            if code == language:
                status = 'current'
            elif code in available_languages:
                status = 'available'
            else:
                status = 'empty'

            tabs.append((url, title, code, status))
            tab_languages.append(code)

        # Additional stale translations in the database?
        if appsettings.PARLER_SHOW_EXCLUDED_LANGUAGE_TABS:
            for code in available_languages:
                if code not in tab_languages:
                    get['language'] = code
                    url = '{0}?{1}'.format(base_url, get.urlencode())

                    if code == language:
                        status = 'current'
                    else:
                        status = 'available'

                    tabs.append((url, get_language_title(code), code, status))

        return tabs
Example #7
0
    def get_language_tabs(self, request, obj, available_languages):
        """
        Determine the language tabs to show.
        """
        tabs = []
        get = request.GET.copy()  # QueryDict object
        language = self.get_form_language(request, obj)
        tab_languages = []

        base_url = '{0}://{1}{2}'.format(request.is_secure() and 'https' or 'http', request.get_host(), request.path)

        for lang_dict in appsettings.PARLER_LANGUAGES.get(settings.SITE_ID, ()):
            code = lang_dict['code']
            title = get_language_title(code)
            get['language'] = code
            url = '{0}?{1}'.format(base_url, get.urlencode())

            if code == language:
                status = 'current'
            elif code in available_languages:
                status = 'available'
            else:
                status = 'empty'

            tabs.append((url, title, code, status))
            tab_languages.append(code)

        # Additional stale translations in the database?
        if appsettings.PARLER_SHOW_EXCLUDED_LANGUAGE_TABS:
            for code in available_languages:
                if code not in tab_languages:
                    get['language'] = code
                    url = '{0}?{1}'.format(base_url, get.urlencode())

                    if code == language:
                        status = 'current'
                    else:
                        status = 'available'

                    tabs.append((url, get_language_title(code), code, status))

        return tabs
Example #8
0
 def deletion_not_allowed(self, request, obj, language_code):
     """
     Deletion-not-allowed view.
     """
     opts = self.model._meta
     context = {
         'object': obj.master,
         'language_code': language_code,
         'opts': opts,
         'app_label': opts.app_label,
         'language_name': get_language_title(language_code),
         'object_name': force_text(opts.verbose_name)
     }
     return render(request, self.deletion_not_allowed_template, context)
Example #9
0
 def deletion_not_allowed(self, request, obj, language_code):
     """
     Deletion-not-allowed view.
     """
     opts = self.model._meta
     context = {
         'object': obj.master,
         'language_code': language_code,
         'opts': opts,
         'app_label': opts.app_label,
         'language_name': get_language_title(language_code),
         'object_name': force_text(opts.verbose_name)
     }
     return render(request, self.deletion_not_allowed_template, context)
Example #10
0
 def deletion_not_allowed(self, request, obj, language_code):
     """
     Deletion-not-allowed view.
     """
     opts = self.model._meta
     context = {
         "object": obj.master,
         "language_code": language_code,
         "opts": opts,
         "app_label": opts.app_label,
         "language_name": get_language_title(language_code),
         "object_name": force_str(opts.verbose_name),
     }
     return render(request, self.deletion_not_allowed_template, context)
Example #11
0
    def render_change_form(self,
                           request,
                           context,
                           add=False,
                           change=False,
                           form_url='',
                           obj=None):
        """
        Insert the language tabs.
        """
        if self._has_translatable_model():
            lang_code = self.get_form_language(request, obj)
            lang = get_language_title(lang_code)

            available_languages = self.get_available_languages(obj)
            current_is_translated = lang_code in available_languages
            language_tabs = self.get_language_tabs(request, obj,
                                                   available_languages)

            context['current_is_translated'] = current_is_translated
            context['allow_deletion'] = len(available_languages) > 1
            context['language_tabs'] = language_tabs
            if language_tabs:
                context['title'] = '%s (%s)' % (context['title'], lang)
            if not current_is_translated:
                add = True  # lets prepopulated_fields_js work.

        # django-fluent-pages uses the same technique
        if 'default_change_form_template' not in context:
            context[
                'default_change_form_template'] = self.get_change_form_base_template(
                )

        #context['base_template'] = self.get_change_form_base_template()
        return super(TranslatableAdmin,
                     self).render_change_form(request, context, add, change,
                                              form_url, obj)
Example #12
0
    def delete_translation(self, request, object_id, language_code):
        """
        The 'delete translation' admin view for this model.
        """
        opts = self.model._meta
        root_model = self.model._parler_meta.root_model

        # Get object and translation
        shared_obj = self.get_object(request, unquote(object_id))
        if shared_obj is None:
            raise Http404

        shared_obj.set_current_language(language_code)
        try:
            translation = root_model.objects.get(master=shared_obj,
                                                 language_code=language_code)
        except root_model.DoesNotExist:
            raise Http404

        if not self.has_delete_permission(request, translation):
            raise PermissionDenied

        if len(self.get_available_languages(shared_obj)) <= 1:
            return self.deletion_not_allowed(request, translation,
                                             language_code)

        # Populate deleted_objects, a data structure of all related objects that
        # will also be deleted.

        using = router.db_for_write(root_model)  # NOTE: all same DB for now.
        lang = get_language_title(language_code)

        # There are potentially multiple objects to delete;
        # the translation object at the base level,
        # and additional objects that can be added by inherited models.
        deleted_objects = []
        perms_needed = False
        protected = []

        # Extend deleted objects with the inlines.
        for qs in self.get_translation_objects(
                request,
                translation.language_code,
                obj=shared_obj,
                inlines=self.delete_inline_translations,
        ):
            if isinstance(qs, (list, tuple)):
                qs_opts = qs[0]._meta
            else:
                qs_opts = qs.model._meta

            if django.VERSION >= (2, 1):
                deleted_result = get_deleted_objects(qs, request,
                                                     self.admin_site)
            else:
                deleted_result = get_deleted_objects(qs, qs_opts, request.user,
                                                     self.admin_site, using)
            (del2, model_counts, perms2, protected2) = deleted_result

            deleted_objects += del2
            perms_needed = perms_needed or perms2
            protected += protected2

        if request.POST:  # The user has already confirmed the deletion.
            if perms_needed:
                raise PermissionDenied
            obj_display = _("{0} translation of {1}").format(
                lang, force_str(translation))  # in hvad: (translation.master)

            self.log_deletion(request, translation, obj_display)
            self.delete_model_translation(request, translation)
            self.message_user(
                request,
                _('The %(name)s "%(obj)s" was deleted successfully.') %
                dict(name=force_str(opts.verbose_name),
                     obj=force_str(obj_display)),
            )

            if self.has_change_permission(request, None):
                info = opts.app_label, opts.model_name
                return HttpResponseRedirect(
                    reverse(
                        "admin:{}_{}_change".format(*info),
                        args=(object_id, ),
                        current_app=self.admin_site.name,
                    ))
            else:
                return HttpResponseRedirect(
                    reverse("admin:index", current_app=self.admin_site.name))

        object_name = _("{0} Translation").format(force_str(opts.verbose_name))
        if perms_needed or protected:
            title = _("Cannot delete %(name)s") % {"name": object_name}
        else:
            title = _("Are you sure?")

        context = {
            "title": title,
            "object_name": object_name,
            "object": translation,
            "deleted_objects": deleted_objects,
            "perms_lacking": perms_needed,
            "protected": protected,
            "opts": opts,
            "app_label": opts.app_label,
        }

        # Small hack for django-polymorphic-tree.
        # This makes sure the breadcrumb renders correctly,
        # and avoids errors when the child model is not registered in the admin.
        if hasattr(self, "base_model"):
            context.update({
                "base_opts": self.base_model._meta,
            })

        return render(
            request,
            self.delete_confirmation_template or [
                f"admin/{opts.app_label}/{opts.object_name.lower()}/delete_confirmation.html",
                "admin/%s/delete_confirmation.html" % opts.app_label,
                "admin/delete_confirmation.html",
            ],
            context,
        )
Example #13
0
 def __str__(self):
     # use format to avoid weird error in django 1.4
     # TypeError: coercing to Unicode: need string or buffer, __proxy__ found
     return "{0}".format(get_language_title(self.language_code))
Example #14
0
 def __unicode__(self):
     return get_language_title(self.language_code)
Example #15
0
 def __unicode__(self):
     # use format to avoid weird error in django 1.4
     # TypeError: coercing to Unicode: need string or buffer, __proxy__ found
     return "{0}".format(get_language_title(self.language_code))
Example #16
0
    def delete_translation(self, request, object_id, language_code):
        """
        The 'delete translation' admin view for this model.
        """
        opts = self.model._meta
        translations_model = self.model._translations_model

        try:
            translation = translations_model.objects.select_related('master').get(master=unquote(object_id), language_code=language_code)
        except translations_model.DoesNotExist:
            raise Http404

        if not self.has_delete_permission(request, translation):
            raise PermissionDenied

        if self.get_available_languages(translation.master).count() <= 1:
            return self.deletion_not_allowed(request, translation, language_code)

        # Populate deleted_objects, a data structure of all related objects that
        # will also be deleted.

        using = router.db_for_write(translations_model)
        lang = get_language_title(language_code)
        (deleted_objects, perms_needed, protected) = get_deleted_objects(
            [translation], translations_model._meta, request.user, self.admin_site, using)

        # Extend deleted objects with the inlines.
        if self.delete_inline_translations:
            shared_obj = translation.master
            for inline, qs in self._get_inline_translations(request, translation.language_code, obj=shared_obj):
                (del2, perms2, protected2) = get_deleted_objects(qs, qs.model._meta, request.user, self.admin_site, using)
                deleted_objects += del2
                perms_needed = perms_needed or perms2
                protected += protected2

        if request.POST: # The user has already confirmed the deletion.
            if perms_needed:
                raise PermissionDenied
            obj_display = _('{0} translation of {1}').format(lang, force_text(translation))  # in hvad: (translation.master)

            self.log_deletion(request, translation, obj_display)
            self.delete_model_translation(request, translation)
            self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % dict(
                name=force_text(opts.verbose_name), obj=force_text(obj_display)
            ))

            if self.has_change_permission(request, None):
                return HttpResponseRedirect(reverse('admin:{0}_{1}_changelist'.format(opts.app_label, opts.module_name)))
            else:
                return HttpResponseRedirect(reverse('admin:index'))

        object_name = _('{0} Translation').format(force_text(opts.verbose_name))
        if perms_needed or protected:
            title = _("Cannot delete %(name)s") % {"name": object_name}
        else:
            title = _("Are you sure?")

        context = {
            "title": title,
            "object_name": object_name,
            "object": translation,
            "deleted_objects": deleted_objects,
            "perms_lacking": perms_needed,
            "protected": protected,
            "opts": opts,
            "app_label": opts.app_label,
        }

        return render(request, self.delete_confirmation_template or [
            "admin/%s/%s/delete_confirmation.html" % (opts.app_label, opts.object_name.lower()),
            "admin/%s/delete_confirmation.html" % opts.app_label,
            "admin/delete_confirmation.html"
        ], context)
Example #17
0
    def delete_translation(self, request, object_id, language_code):
        """
        The 'delete translation' admin view for this model.
        """
        opts = self.model._meta
        root_model = self.model._parler_meta.root_model

        # Get object and translation
        shared_obj = self.get_object(request, unquote(object_id))
        if shared_obj is None:
            raise Http404

        shared_obj.set_current_language(language_code)
        try:
            translation = root_model.objects.get(master=shared_obj,
                                                 language_code=language_code)
        except root_model.DoesNotExist:
            raise Http404

        if not self.has_delete_permission(request, translation):
            raise PermissionDenied

        if self.get_available_languages(shared_obj).count() <= 1:
            return self.deletion_not_allowed(request, translation,
                                             language_code)

        # Populate deleted_objects, a data structure of all related objects that
        # will also be deleted.

        using = router.db_for_write(root_model)  # NOTE: all same DB for now.
        lang = get_language_title(language_code)

        # There are potentially multiple objects to delete;
        # the translation object at the base level,
        # and additional objects that can be added by inherited models.
        deleted_objects = []
        perms_needed = False
        protected = []

        # Extend deleted objects with the inlines.
        for qs in self.get_translation_objects(
                request,
                translation.language_code,
                obj=shared_obj,
                inlines=self.delete_inline_translations):
            if isinstance(qs, (list, tuple)):
                qs_opts = qs[0]._meta
            else:
                qs_opts = qs.model._meta

            deleted_result = get_deleted_objects(qs, qs_opts, request.user,
                                                 self.admin_site, using)
            if django.VERSION >= (1, 8):
                (del2, model_counts, perms2, protected2) = deleted_result
            else:
                (del2, perms2, protected2) = deleted_result

            deleted_objects += del2
            perms_needed = perms_needed or perms2
            protected += protected2

        if request.POST:  # The user has already confirmed the deletion.
            if perms_needed:
                raise PermissionDenied
            obj_display = _('{0} translation of {1}').format(
                lang, force_text(translation))  # in hvad: (translation.master)

            self.log_deletion(request, translation, obj_display)
            self.delete_model_translation(request, translation)
            self.message_user(
                request,
                _('The %(name)s "%(obj)s" was deleted successfully.') %
                dict(name=force_text(opts.verbose_name),
                     obj=force_text(obj_display)))

            if self.has_change_permission(request, None):
                return HttpResponseRedirect(
                    reverse('admin:{0}_{1}_changelist'.format(
                        opts.app_label, opts.model_name if django.VERSION >=
                        (1, 7) else opts.module_name)))
            else:
                return HttpResponseRedirect(reverse('admin:index'))

        object_name = _('{0} Translation').format(force_text(
            opts.verbose_name))
        if perms_needed or protected:
            title = _("Cannot delete %(name)s") % {"name": object_name}
        else:
            title = _("Are you sure?")

        context = {
            "title": title,
            "object_name": object_name,
            "object": translation,
            "deleted_objects": deleted_objects,
            "perms_lacking": perms_needed,
            "protected": protected,
            "opts": opts,
            "app_label": opts.app_label,
        }

        return render(
            request, self.delete_confirmation_template or [
                "admin/%s/%s/delete_confirmation.html" %
                (opts.app_label, opts.object_name.lower()),
                "admin/%s/delete_confirmation.html" % opts.app_label,
                "admin/delete_confirmation.html"
            ], context)
Example #18
0
    def delete_translation(self, request, object_id, language_code):
        """
        The 'delete translation' admin view for this model.
        """
        opts = self.model._meta
        root_model = self.model._parler_meta.root_model

        # Get object and translation
        shared_obj = self.get_object(request, unquote(object_id))
        if shared_obj is None:
            raise Http404

        shared_obj.set_current_language(language_code)
        try:
            translation = root_model.objects.get(master=shared_obj, language_code=language_code)
        except root_model.DoesNotExist:
            raise Http404

        if not self.has_delete_permission(request, translation):
            raise PermissionDenied

        if len(self.get_available_languages(shared_obj)) <= 1:
            return self.deletion_not_allowed(request, translation, language_code)

        # Populate deleted_objects, a data structure of all related objects that
        # will also be deleted.

        using = router.db_for_write(root_model)  # NOTE: all same DB for now.
        lang = get_language_title(language_code)

        # There are potentially multiple objects to delete;
        # the translation object at the base level,
        # and additional objects that can be added by inherited models.
        deleted_objects = []
        perms_needed = False
        protected = []

        # Extend deleted objects with the inlines.
        for qs in self.get_translation_objects(request, translation.language_code, obj=shared_obj, inlines=self.delete_inline_translations):
            if isinstance(qs, (list, tuple)):
                qs_opts = qs[0]._meta
            else:
                qs_opts = qs.model._meta

            deleted_result = get_deleted_objects(qs, qs_opts, request.user, self.admin_site, using)
            if django.VERSION >= (1, 8):
                (del2, model_counts, perms2, protected2) = deleted_result
            else:
                (del2, perms2, protected2) = deleted_result

            deleted_objects += del2
            perms_needed = perms_needed or perms2
            protected += protected2

        if request.POST: # The user has already confirmed the deletion.
            if perms_needed:
                raise PermissionDenied
            obj_display = _('{0} translation of {1}').format(lang, force_text(translation))  # in hvad: (translation.master)

            self.log_deletion(request, translation, obj_display)
            self.delete_model_translation(request, translation)
            self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % dict(
                name=force_text(opts.verbose_name), obj=force_text(obj_display)
            ))

            if self.has_change_permission(request, None):
                info = _get_model_meta(opts)
                return HttpResponseRedirect(reverse('admin:{0}_{1}_change'.format(*info), args=(object_id,), current_app=self.admin_site.name))
            else:
                return HttpResponseRedirect(reverse('admin:index', current_app=self.admin_site.name))

        object_name = _('{0} Translation').format(force_text(opts.verbose_name))
        if perms_needed or protected:
            title = _("Cannot delete %(name)s") % {"name": object_name}
        else:
            title = _("Are you sure?")

        context = {
            "title": title,
            "object_name": object_name,
            "object": translation,
            "deleted_objects": deleted_objects,
            "perms_lacking": perms_needed,
            "protected": protected,
            "opts": opts,
            "app_label": opts.app_label,
        }

        return render(request, self.delete_confirmation_template or [
            "admin/%s/%s/delete_confirmation.html" % (opts.app_label, opts.object_name.lower()),
            "admin/%s/delete_confirmation.html" % opts.app_label,
            "admin/delete_confirmation.html"
        ], context)
Example #19
0
    def delete_translation(self, request, object_id, language_code):
        """
        The 'delete translation' admin view for this model.
        """
        opts = self.model._meta
        translations_model = self.model._translations_model

        try:
            translation = translations_model.objects.select_related(
                'master').get(master=unquote(object_id),
                              language_code=language_code)
        except translations_model.DoesNotExist:
            raise Http404

        if not self.has_delete_permission(request, translation):
            raise PermissionDenied

        if self.get_available_languages(translation.master).count() <= 1:
            return self.deletion_not_allowed(request, translation,
                                             language_code)

        # Populate deleted_objects, a data structure of all related objects that
        # will also be deleted.

        using = router.db_for_write(translations_model)
        lang = get_language_title(language_code)
        (deleted_objects, perms_needed,
         protected) = get_deleted_objects([translation],
                                          translations_model._meta,
                                          request.user, self.admin_site, using)

        # Extend deleted objects with the inlines.
        if self.delete_inline_translations:
            shared_obj = translation.master
            for inline, qs in self._get_inline_translations(
                    request, translation.language_code, obj=shared_obj):
                (del2, perms2,
                 protected2) = get_deleted_objects(qs, qs.model._meta,
                                                   request.user,
                                                   self.admin_site, using)
                deleted_objects += del2
                perms_needed = perms_needed or perms2
                protected += protected2

        if request.POST:  # The user has already confirmed the deletion.
            if perms_needed:
                raise PermissionDenied
            obj_display = _('{0} translation of {1}').format(
                lang, force_text(translation))  # in hvad: (translation.master)

            self.log_deletion(request, translation, obj_display)
            self.delete_model_translation(request, translation)
            self.message_user(
                request,
                _('The %(name)s "%(obj)s" was deleted successfully.') %
                dict(name=force_text(opts.verbose_name),
                     obj=force_text(obj_display)))

            if self.has_change_permission(request, None):
                return HttpResponseRedirect(
                    reverse('admin:{0}_{1}_changelist'.format(
                        opts.app_label, opts.module_name)))
            else:
                return HttpResponseRedirect(reverse('admin:index'))

        object_name = _('{0} Translation').format(force_text(
            opts.verbose_name))
        if perms_needed or protected:
            title = _("Cannot delete %(name)s") % {"name": object_name}
        else:
            title = _("Are you sure?")

        context = {
            "title": title,
            "object_name": object_name,
            "object": translation,
            "deleted_objects": deleted_objects,
            "perms_lacking": perms_needed,
            "protected": protected,
            "opts": opts,
            "app_label": opts.app_label,
        }

        return render(
            request, self.delete_confirmation_template or [
                "admin/%s/%s/delete_confirmation.html" %
                (opts.app_label, opts.object_name.lower()),
                "admin/%s/delete_confirmation.html" % opts.app_label,
                "admin/delete_confirmation.html"
            ], context)
Example #20
0
 def __unicode__(self):
     return get_language_title(self.language_code)
Example #21
0
 def __str__(self):
     return force_text(get_language_title(self.language_code))