def get_i18n_form(self, request, obj=None, **kwargs): """ Returns a Form class for use in the admin add view. This is used by add_view and change_view. """ fields = get_translation_opt(self.model, 'translatable_fields') if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(kwargs.get("exclude", [])) exclude.extend(self.get_readonly_fields(request, obj)) # if exclude is an empty list we pass None to be consistant with the # default on modelform_factory exclude = exclude or None if self.form and hasattr(self.form, 'declared_fields'): for field in list(self.form.declared_fields.keys()): if field not in fields: self.form.declared_fields.pop(field) formfield_callback = curry(self.formfield_for_dbfield, request=request) defaults = { "form": self.form, "fields": fields, "exclude": exclude, "formfield_callback": formfield_callback, } defaults.update(kwargs) f = modelform_factory(self.Tmodel, **defaults) f.clean = lambda s: s.cleaned_data return f
def get_prepopulated_fields_inline(inline, request): # FIX for 1.3 if hasattr(inline, 'get_prepopulated_fields'): prepopulated_fields = inline.get_prepopulated_fields(request) else: prepopulated_fields = inline.prepopulated_fields translatable_fields = get_translation_opt(inline.model, 'translatable_fields') for k, v in prepopulated_fields.items(): if k not in translatable_fields or v not in translatable_fields: prepopulated_fields.pop(k) return prepopulated_fields
def get_prepopulated_fields(self, request, *args, **kwargs): # FIX for 1.3 superadmin = super(TranslationModelAdmin, self) if hasattr(superadmin, 'get_prepopulated_fields'): prepopulated_fields = superadmin.get_prepopulated_fields(request, *args, **kwargs) else: prepopulated_fields = self.prepopulated_fields translatable_fields = get_translation_opt(self.model, 'translatable_fields') for k, v in prepopulated_fields.items(): if k not in translatable_fields or v not in translatable_fields: prepopulated_fields.pop(k) return prepopulated_fields
def get_inline_form(self, inline): class TransInlineForm(inline.form): def __init__(self, *args, **kwargs): super(TransInlineForm, self).__init__(*args, **kwargs) for fn in self.fields: if fn not in self.i18n_fields: self.fields[fn].widget = SpanPostWidget( ) # forms.HiddenInput() if self.instance.pk: val = getattr(self.instance, fn, '') self.fields[ fn].widget.original_value = val.pk if hasattr( val, 'pk') else val self.fields[fn].widget.display_value = unicode(val) # self.fields[fn].widget.attrs['READONLY'] = 'READONLY' # choices = getattr(self.fields[fn].widget, 'choices', None) # if choices and 'instance' in kwargs: # val = getattr(kwargs['instance'], fn, '') # choices = [(k, v) for k,v in dict(choices).items() if k == val] # self.fields[fn].widget.choices = choices # else: # self.fields[fn].widget.attrs['DISABLED'] = 'DISABLED' def save(self, *args, **kwargs): kwargs['commit'] = False obj = super(TransInlineForm, self).save(*args, **kwargs) Tmodel = obj.__class__._translation_model defaults = { '_master': self.instance, '_language': self.lang.replace("-", "") } try: aux = Tmodel.objects.get(**defaults) except Tmodel.DoesNotExist: aux = Tmodel(**defaults) trans_meta = self.instance._translation_model._transmeta fields = trans_meta.translatable_fields for name in fields: value = getattr(obj, name, None) if not value is None: setattr(aux, name, value) aux.save() self.instance.translations.add(aux) return aux TransInlineForm.lang = self.lang TransInlineForm.i18n_fields = get_translation_opt( inline.model, 'translatable_fields') return TransInlineForm
def i18n_save(instance, language, values={}, delete=False): if language not in dict(settings.LANGUAGES): raise ValueError(_('Incorrect language %(lang)s') % {'lang': language}) master_language = get_translation_opt(instance, 'master_language') if language == master_language: return instance.save() trans_id = getattr(instance, 'id_%s' % language, None) if not trans_id and delete: # This objects has no translation to language "language" return if delete: instance._translation_model.objects.filter(id=trans_id).delete() else: return instance._translation_model.objects.filter(id=trans_id).update(**values)
def get_inline_form(self, inline): class TransInlineForm(inline.form): def __init__(self, *args, **kwargs): super(TransInlineForm, self).__init__(*args, **kwargs) for fn in self.fields: if fn not in self.i18n_fields: self.fields[fn].widget = SpanPostWidget() # forms.HiddenInput() if self.instance.pk: val = getattr(self.instance, fn, '') self.fields[fn].widget.original_value = val.pk if hasattr(val, 'pk') else val self.fields[fn].widget.display_value = unicode(val) # self.fields[fn].widget.attrs['READONLY'] = 'READONLY' # choices = getattr(self.fields[fn].widget, 'choices', None) # if choices and 'instance' in kwargs: # val = getattr(kwargs['instance'], fn, '') # choices = [(k, v) for k,v in dict(choices).items() if k == val] # self.fields[fn].widget.choices = choices # else: # self.fields[fn].widget.attrs['DISABLED'] = 'DISABLED' def save(self, *args, **kwargs): kwargs['commit'] = False obj = super(TransInlineForm, self).save(*args, **kwargs) Tmodel = obj.__class__._translation_model defaults = { '_master': self.instance, '_language': self.lang.replace("-", "").lower() } try: aux = Tmodel.objects.get(**defaults) except Tmodel.DoesNotExist: aux = Tmodel(**defaults) trans_meta = self.instance._translation_model._transmeta fields = trans_meta.translatable_fields for name in fields: value = getattr(obj, name, None) if not value is None: setattr(aux, name, value) aux.save() self.instance.translations.add(aux) return aux TransInlineForm.lang = self.lang TransInlineForm.i18n_fields = get_translation_opt(inline.model, 'translatable_fields') return TransInlineForm
def filter(self, *args, **kwargs): if self.lang and self.lang != get_master_language(self.model): from model_i18n.utils import get_translation_opt translatable_fields = \ get_translation_opt(self.model, 'translatable_fields') aps = [] for k, v in kwargs.items(): if "translations" not in k and k in translatable_fields: k = "translations__%s" % k aps.append(Q(**{k: v})) if aps: qu = aps.pop() for item in aps: qu &= item return super(TransQuerySet, self).filter(qu) return super(TransQuerySet, self).filter(*args, **kwargs)
def i18n_save(instance, language, values={}, delete=False): if language not in dict(settings.LANGUAGES): raise ValueError(_('Incorrect language %(lang)s') % {'lang': language}) master_language = get_translation_opt(instance, 'master_language') if language == master_language: return instance.save() trans_id = getattr(instance, 'id_%s' % language, None) if not trans_id and delete: # This objects has no translation to language "language" return if delete: instance._translation_model.objects.filter(id=trans_id).delete() else: return instance._translation_model.objects.filter(id=trans_id).update( **values)
def i18n_change_view(self, request, object_id, language, extra=None): "The 'change' admin view for this model." cur_language = translation.get_language() translation.activate(language) model = self.model opts = model._meta self.lang = language obj = self.get_object(request, unquote(object_id)) Tobj = self.get_i18n_object(request, unquote(object_id), obj, language) if not self.has_change_permission(request, obj): raise PermissionDenied master_language = get_translation_opt(self.model, 'master_language') if language == master_language: # redirect to instance admin on default language return HttpResponseRedirect('../') if obj is None: raise Http404(_('%(name)s object with primary key %(key)r \ does not exist.') % {'name': force_unicode(opts.verbose_name), \ 'key': escape(object_id)}) if language not in dict(settings.LANGUAGES): raise Http404(_('Incorrect language %(l)s') % {'l': language}) ModelForm = self.get_form(request, Tobj) formsets = [] if request.method == 'POST': form = ModelForm(request.POST, request.FILES, instance=Tobj) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=True) else: form_validated = False new_object = Tobj prefixes = {} for FormSet, inline in zip(self.get_formsets(request, new_object), self.get_inline_instances(request)): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(request.POST, request.FILES, instance=new_object._master, prefix=prefix, queryset=inline.queryset(request)) formsets.append(formset) all_valid = True for fs in formsets: if not fs.is_valid(): all_valid = False if all_valid and form_validated: self.save_model(request, new_object, form, change=True) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=True) change_message = \ self.construct_change_message(request, form, formsets) self.log_change(request, new_object, change_message) self.lang = None return self.response_change(request, new_object) else: form = ModelForm(instance=Tobj) prefixes = {} for FormSet, inline in \ zip(self.get_formsets(request, Tobj._master), \ self.get_inline_instances(request)): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=Tobj._master, prefix=prefix, queryset=None) formsets.append(formset) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.get_prepopulated_fields(request), self.get_readonly_fields(request), model_admin=self) media = self.media + adminForm.media def get_prepopulated_fields_inline(inline, request): # FIX for 1.3 if hasattr(inline, 'get_prepopulated_fields'): prepopulated_fields = inline.get_prepopulated_fields(request) else: prepopulated_fields = inline.prepopulated_fields translatable_fields = get_translation_opt(inline.model, 'translatable_fields') for k, v in prepopulated_fields.items(): if k not in translatable_fields or v not in translatable_fields: prepopulated_fields.pop(k) return prepopulated_fields inline_admin_formsets = [] for inline, formset in zip(self.get_inline_instances(request), formsets): if not hasattr(inline.model, '_translation_model'): continue fieldsets = list(inline.get_fieldsets(request)) readonly = list(inline.get_readonly_fields(request)) prepopulated = dict(get_prepopulated_fields_inline(inline, request)) inline_kwargs = {} # FIX for 1.3 if '1.4' in get_django_version(): inline_kwargs['model_admin'] = self inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets, prepopulated, readonly, **inline_kwargs) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media translated_fields = [] for f in obj._translation_model._transmeta.translatable_fields: try: v = getattr(obj, '_'.join((f, 'master'))) except: v = getattr(obj, f,) v = v or '' if hasattr(v, 'replace'): v = v.replace("'", "'").replace('"', """) v = v.replace('\r', '') v = v.replace('\n', '<br>') translated_fields.append((f, v)) context = { 'title': _('Translation %s') % force_unicode(opts.verbose_name), 'tiny_mce': True, 'adminform': adminForm, 'original': obj, 'translated_fields': translated_fields, 'master_language': master_language, 'is_popup': ('_popup' in request.REQUEST), 'errors': admin.helpers.AdminErrorList(form, []), #'root_path': self.admin_site.root_path, 'app_label': opts.app_label, 'trans': True, 'lang': language, 'current_language': dict(settings.LANGUAGES)[language], 'inline_admin_formsets': inline_admin_formsets, 'media': media, # override some values to provide an useful template 'add': False, 'change': True, 'has_change_permission_orig': True, # backup 'has_add_permission': False, 'has_change_permission': False, 'has_delete_permission': False, # hide delete link for now 'has_file_field': True, 'save_as': False, 'opts': self.model._meta, } translation.activate(cur_language) self.lang = None ctx = RequestContext(request, current_app=self.admin_site.name) change_form_template = [ "admin/%s/%s/change_form.html" % (opts.app_label, opts.object_name.lower()), CHANGE_TRANSLATION_TPL, "admin/%s/change_form.html" % opts.app_label, "admin/change_form.html", ] return render_to_response(change_form_template, context, context_instance=ctx)
def i18n_change_view(instance, request, obj_id, language): """Change view for i18n values for current instance. This is a simplified django-admin change view which displays i18n fields for current model/id.""" opts = instance.model._meta obj = instance.get_object(request, obj_id) if not instance.has_change_permission(request, obj): raise PermissionDenied if obj is None: msg = _("%(name)s object with primary key %(key)r does not exist.") raise Http404(msg % {"name": force_unicode(opts.verbose_name), "key": escape(obj_id)}) if language not in dict(settings.LANGUAGES): raise Http404(_("Incorrect language %(lang)s") % {"lang": language}) master_language = get_translation_opt(obj, "master_language") if language == master_language: # redirect to instance admin on default language return HttpResponseRedirect("../") fields = get_translation_opt(obj, "translatable_fields") lang_field = get_translation_opt(obj, "language_field_name") master_field = get_translation_opt(obj, "master_field_name") related_name = get_translation_opt(obj, "related_name") try: manager = getattr(obj, related_name) # search for related_name manager if manager is None: # if related_name in None use default value "translations" manager = obj.translations trans = manager.get(**{lang_field: language}) except obj._translation_model.DoesNotExist: # new translation trans = obj._translation_model(**{lang_field: language, master_field: obj}) ModelForm = modelform_factory(obj._translation_model, fields=fields) if request.method == "POST": form = ModelForm(instance=trans, data=request.POST, files=request.FILES) if form.is_valid(): form.save() return HttpResponseRedirect("../../") else: form = ModelForm(instance=trans) adminform = admin.helpers.AdminForm(form, [(None, {"fields": fields})], {}, None) context = { "title": _("Translation %s") % force_unicode(opts.verbose_name), "adminform": adminform, "original": obj, "is_popup": request.REQUEST.has_key("_popup"), "errors": admin.helpers.AdminErrorList(form, None), "root_path": instance.admin_site.root_path, "app_label": opts.app_label, "trans": True, "lang": language, "current_language": dict(settings.LANGUAGES)[language], # override some values to provide an useful template "add": False, "change": True, "has_change_permission_orig": True, # backup "has_add_permission": False, "has_change_permission": False, "has_delete_permission": False, # hide delete link for now "has_file_field": True, "save_as": False, "opts": instance.model._meta, } ctx = RequestContext(request, current_app=instance.admin_site.name) return render_to_response(CHANGE_TRANSLATION_TPL, context, context_instance=ctx)
def i18n_change_view(self, request, object_id, language, extra=None): "The 'change' admin view for this model." cur_language = translation.get_language() translation.activate(language) model = self.model opts = model._meta self.lang = language obj = self.get_object(request, unquote(object_id)) Tobj = self.get_i18n_object(request, unquote(object_id), obj, language) if not self.has_change_permission(request, obj): raise PermissionDenied master_language = get_translation_opt(self.model, 'master_language') if language == master_language: # redirect to instance admin on default language return HttpResponseRedirect('../') if obj is None: raise Http404(_('%(name)s object with primary key %(key)r \ does not exist.') % {'name': force_unicode(opts.verbose_name), \ 'key': escape(object_id)}) if language not in dict(settings.LANGUAGES): raise Http404(_('Incorrect language %(l)s') % {'l': language}) ModelForm = self.get_form(request, Tobj) formsets = [] if request.method == 'POST': form = ModelForm(request.POST, request.FILES, instance=Tobj) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=True) else: form_validated = False new_object = Tobj prefixes = {} for FormSet, inline in zip(self.get_formsets(request, new_object), self.get_inline_instances(*get_inline_instances_args(self, request, new_object))): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(request.POST, request.FILES, instance=new_object._master, prefix=prefix, queryset=inline.queryset(request)) formsets.append(formset) all_valid = True for fs in formsets: if not fs.is_valid(): all_valid = False if all_valid and form_validated: self.save_model(request, new_object, form, change=True) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=True) change_message = \ self.construct_change_message(request, form, formsets) self.log_change(request, new_object, change_message) self.lang = None return self.response_change(request, new_object) else: form = ModelForm(instance=Tobj) prefixes = {} for FormSet, inline in \ zip(self.get_formsets(request, Tobj._master), \ self.get_inline_instances(*get_inline_instances_args(self, request, Tobj))): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=Tobj._master, prefix=prefix, queryset=None) formsets.append(formset) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.get_prepopulated_fields(request), self.get_readonly_fields(request), model_admin=self) media = self.media + adminForm.media def get_prepopulated_fields_inline(inline, request): # FIX for 1.3 if hasattr(inline, 'get_prepopulated_fields'): prepopulated_fields = inline.get_prepopulated_fields(request) else: prepopulated_fields = inline.prepopulated_fields translatable_fields = get_translation_opt(inline.model, 'translatable_fields') for k, v in prepopulated_fields.items(): if k not in translatable_fields or v not in translatable_fields: prepopulated_fields.pop(k) return prepopulated_fields inline_admin_formsets = [] for inline, formset in zip(self.get_inline_instances(*get_inline_instances_args(self, request, obj)), formsets): if not hasattr(inline.model, '_translation_model'): continue fieldsets = list(inline.get_fieldsets(request)) readonly = list(inline.get_readonly_fields(request)) prepopulated = dict(get_prepopulated_fields_inline(inline, request)) inline_kwargs = {} # FIX for 1.3 if '1.4' in get_django_version(): inline_kwargs['model_admin'] = self inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets, prepopulated, readonly, **inline_kwargs) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media translated_fields = [] for f in obj._translation_model._transmeta.translatable_fields: try: v = getattr(obj, '_'.join((f, 'master'))) except: v = getattr(obj, f,) v = v or '' if hasattr(v, 'replace'): v = v.replace("'", "'").replace('"', """) v = v.replace('\r', '') v = v.replace('\n', '<br>') translated_fields.append((f, v)) context = { 'title': _('Translation %s') % force_unicode(opts.verbose_name), 'tiny_mce': True, 'adminform': adminForm, 'original': obj, 'translated_fields': translated_fields, 'master_language': master_language, 'is_popup': ('_popup' in request.REQUEST), 'errors': admin.helpers.AdminErrorList(form, []), #'root_path': self.admin_site.root_path, 'app_label': opts.app_label, 'trans': True, 'lang': language, 'current_language': dict(settings.LANGUAGES)[language], 'inline_admin_formsets': inline_admin_formsets, # override some values to provide an useful template 'add': False, 'change': True, 'has_change_permission_orig': True, # backup 'has_add_permission': False, 'has_change_permission': False, 'has_delete_permission': False, # hide delete link for now 'has_file_field': True, 'save_as': False, 'opts': self.model._meta, } translation.activate(cur_language) self.lang = None ctx = RequestContext(request, current_app=self.admin_site.name) change_form_template = [ "admin/%s/%s/change_form.html" % (opts.app_label, opts.object_name.lower()), CHANGE_TRANSLATION_TPL, "admin/%s/change_form.html" % opts.app_label, "admin/change_form.html", ] return render_to_response(change_form_template, context, context_instance=ctx)
def i18n_change_view(instance, request, obj_id, language): """Change view for i18n values for current instance. This is a simplified django-admin change view which displays i18n fields for current model/id.""" opts = instance.model._meta obj = instance.get_object(request, obj_id) if not instance.has_change_permission(request, obj): raise PermissionDenied if obj is None: msg = _('%(name)s object with primary key %(key)r does not exist.') raise Http404(msg % {'name': force_unicode(opts.verbose_name), 'key': escape(obj_id)}) if language not in dict(settings.LANGUAGES): raise Http404(_('Incorrect language %(lang)s') % {'lang': language}) master_language = get_translation_opt(obj, 'master_language') if language == master_language: # redirect to instance admin on default language return HttpResponseRedirect('../') fields = get_translation_opt(obj, 'translatable_fields') lang_field = get_translation_opt(obj, 'language_field_name') master_field = get_translation_opt(obj, 'master_field_name') related_name = get_translation_opt(obj, 'related_name') try: manager = getattr(obj, related_name) # search for related_name manager if manager is None: # if related_name in None use default value "translations" manager = obj.translations trans = manager.get(**{lang_field: language}) except obj._translation_model.DoesNotExist: # new translation trans = obj._translation_model(**{lang_field: language, master_field: obj}) ModelForm = modelform_factory(obj._translation_model, fields=fields) if request.method == 'POST': form = ModelForm(instance=trans, data=request.POST, files=request.FILES) if form.is_valid(): form.save() return HttpResponseRedirect('../../') else: form = ModelForm(instance=trans) adminform = admin.helpers.AdminForm(form, [(None, {'fields': fields})], {}, None) context = { 'title': _('Translation %s') % force_unicode(opts.verbose_name), 'adminform': adminform, 'original': obj, 'is_popup': request.REQUEST.has_key('_popup'), 'errors': admin.helpers.AdminErrorList(form, None), 'root_path': instance.admin_site.root_path, 'app_label': opts.app_label, 'trans': True, 'lang': language, 'current_language': dict(settings.LANGUAGES)[language], # override some values to provide an useful template 'add': False, 'change': True, 'has_change_permission_orig': True, # backup 'has_add_permission': False, 'has_change_permission': False, 'has_delete_permission': False, # hide delete link for now 'has_file_field': True, 'save_as': False, 'opts': instance.model._meta, } ctx = RequestContext(request, current_app=instance.admin_site.name) return render_to_response(CHANGE_TRANSLATION_TPL, context, context_instance=ctx)
def i18n_change_view(instance, request, obj_id, language): """Change view for i18n values for current instance. This is a simplified django-admin change view which displays i18n fields for current model/id.""" opts = instance.model._meta obj = instance.get_object(request, obj_id) if not instance.has_change_permission(request, obj): raise PermissionDenied if obj is None: msg = _('%(name)s object with primary key %(key)r does not exist.') raise Http404(msg % { 'name': force_unicode(opts.verbose_name), 'key': escape(obj_id) }) if language not in dict(settings.LANGUAGES): raise Http404(_('Incorrect language %(lang)s') % {'lang': language}) master_language = get_translation_opt(obj, 'master_language') if language == master_language: # redirect to instance admin on default language return HttpResponseRedirect('../') fields = get_translation_opt(obj, 'translatable_fields') lang_field = get_translation_opt(obj, 'language_field_name') master_field = get_translation_opt(obj, 'master_field_name') try: trans = obj.translations.get(**{lang_field: language}) except obj._translation_model.DoesNotExist: # new translation trans = obj._translation_model(**{ lang_field: language, master_field: obj }) ModelForm = modelform_factory(obj._translation_model, fields=fields) if request.method == 'POST': form = ModelForm(instance=trans, data=request.POST, files=request.FILES) if form.is_valid(): form.save() return HttpResponseRedirect(request.path) else: form = ModelForm(instance=trans) adminform = admin.helpers.AdminForm(form, [(None, { 'fields': fields })], {}, None) context = { 'title': _('Translation %s') % force_unicode(opts.verbose_name), 'adminform': adminform, 'original': obj, 'is_popup': request.REQUEST.has_key('_popup'), 'errors': admin.helpers.AdminErrorList(form, None), 'root_path': instance.admin_site.root_path, 'app_label': opts.app_label, 'trans': True, 'lang': language, 'current_language': dict(settings.LANGUAGES)[language], # override some values to provide an useful template 'add': False, 'change': True, 'has_change_permission_orig': True, # backup 'has_add_permission': False, 'has_change_permission': False, 'has_delete_permission': False, # hide delete link for now 'has_file_field': True, 'save_as': False, 'opts': instance.model._meta, } ctx = RequestContext(request, current_app=instance.admin_site.name) return render_to_response(CHANGE_TRANSLATION_TPL, context, context_instance=ctx)