def get_localized_field_name(context, field): """Get the name of the localized field""" attrs = [ translation.get_language(), translation.get_language()[:2], settings.LANGUAGE_CODE ] def predicate(x): field_name = get_real_fieldname(field, x) if hasattr(context, field_name): return field_name return None return first_match(predicate, attrs)
def get_localized_property(context, field=None, language=None): ''' When accessing to the name of the field itself, the value in the current language will be returned. Unless it's set, the value in the default language will be returned. ''' if language: return getattr(context, get_real_fieldname(field, language)) if hasattr(settings, 'FALLBACK_LANGUAGES'): attrs = [translation.get_language()] attrs += get_fallback_languages() else: attrs = [ translation.get_language(), translation.get_language()[:2], settings.LANGUAGE_CODE, ] def predicate(x): value = getattr(context, get_real_fieldname(field, x), None) return value if valid_for_gettext(value) else None return first_match(predicate, attrs)
def test_first_true(self): assert(first_match(lambda x: x or None, self.arr))
def test_first_true(self): assert (first_match(lambda x: x or None, self.arr))
def render_revision_form(self, request, obj, version, context, revert=False, recover=False): """Renders the object revision form.""" model = self.model opts = model._meta object_id = obj.pk # Generate the model form. ModelForm = self.get_form(request, obj) formsets = [] if request.method == "POST": # This section is copied directly from the model admin change view # method. Maybe one day there will be a hook for doing this better. form = ModelForm(request.POST, request.FILES, instance=obj, initial=self.get_revision_form_data(request, obj, version)) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=True) else: form_validated = False new_object = obj prefixes = {} for FormSet, inline in zip(self.get_formsets(request, new_object), self.inline_instances): 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, prefix=prefix, queryset=inline.queryset(request)) # _ _ _ ____ ___ ____ _ _ ____ _ _ ___ # | | | |__| | | |__| | | | | | # |_|_| | | | |___ | | |__| |__| | # this is not copy pasted: # Strip extra empty forms from the formset. empty_forms = [] post_keys = request.POST.keys() for f in formset.forms: # the forms that can be removed, are not in the request.POST # we can find them by their prefix matches_prefix = lambda var: var.find(f.prefix) == 0 or None if first_match(matches_prefix, post_keys) is None: empty_forms.append(f) else: # the form must be cleaned, which they aren't yet because # we just created them f.full_clean() # modify form settings of formset. num_forms = formset.total_form_count() - len(empty_forms) formset.forms = filter(lambda x: x not in empty_forms, formset.forms) formset.total_form_count = lambda: num_forms # end of non copy pasted piece # Add this hacked formset to the form. formsets.append(formset) if all_valid(formsets) 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) # _ _ _ ____ ___ ____ _ _ ____ _ _ ___ # | | | |__| | | |__| | | | | | # |_|_| | | | |___ | | |__| |__| | # this is not copy pasted: self.update_draft(version, request) change_message = _(u"Publisher message %(datetime)s") % {"datetime": format(version.revision.date_created, _(settings.DATETIME_FORMAT))} self.log_change(request, new_object, change_message) self.message_user(request, _(u'%(model)s "%(name)s" publisher message.') % {"model": force_unicode(opts.verbose_name), "name": unicode(obj)}) # end of not copy pasted code # Redirect to the model change form. if revert: return HttpResponseRedirect("../../") elif recover: return HttpResponseRedirect("../../%s/" % object_id) else: assert False else: # This is a mutated version of the code in the standard model admin # change_view. Once again, a hook for this kind of functionality # would be nice. Unfortunately, it results in doubling the number # of queries required to construct the formets. form = ModelForm(instance=obj, initial=self.get_revision_form_data(request, obj, version)) prefixes = {} revision_versions = version.revision.version_set.all() for FormSet, inline in zip(self.get_formsets(request, obj), self.inline_instances): # This code is standard for creating the formset. 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=obj, prefix=prefix, queryset=inline.queryset(request)) # Now we hack it to push in the data from the revision! try: fk_name = FormSet.fk.name except AttributeError: # This is a GenericInlineFormset, or similar. fk_name = FormSet.ct_fk_field.name # _ _ _ ____ ___ ____ _ _ ____ _ _ ___ # | | | |__| | | |__| | | | | | # |_|_| | | | |___ | | |__| |__| | # this is not copy pasted: related_versions = [(related_version.object_id, related_version) for related_version in revision_versions if ContentType.objects.get_for_id(related_version.content_type_id).model_class() == FormSet.model and unicode(related_version.field_dict[fk_name]) == unicode(object_id)] # all items that do not have their id filled in must stay. # if they do in fact have an id, we only want the last one, # no duplicates. related_versions = [(key, value) for (key, value) in related_versions if key == 'None'] + \ dict([(key, value) for (key, value) in related_versions if key != 'None']).items() initial = [] for related_obj in formset.queryset: related_versions_dict = dict(related_versions) if unicode(related_obj.pk) in related_versions_dict: initial.append(related_versions_dict.pop(unicode(related_obj.pk)).field_dict) else: initial_data = model_to_dict(related_obj) initial_data["DELETE"] = True initial.append(initial_data) for (key, related_version) in related_versions: initial_row = related_version.field_dict try: del initial_row["id"] except KeyError: # when multiple inlines with the same model but a different # querysets are on a page, it could happen that we allready # deleted the id. pass # we didn't convert related_versions to a dict so there can be # duplicate keys in the thingy if not initial_row in initial: initial.append(initial_row) # end of non copy pasted piece # Reconstruct the forms with the new revision data. formset.initial = initial formset.forms = [formset._construct_form(n) for n in xrange(len(initial))] # Add this hacked formset to the form. formsets.append(formset) # Generate admin form helper. adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields, self.get_readonly_fields(request, obj), model_admin=self) media = self.media + adminForm.media # Generate formset helpers. inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request, obj)) readonly = list(inline.get_readonly_fields(request, obj)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets, readonly, model_admin=self) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media # Generate the context. context.update({"adminform": adminForm, "object_id": object_id, "original": obj, "is_popup": False, "media": mark_safe(media), "inline_admin_formsets": inline_admin_formsets, "errors": helpers.AdminErrorList(form, formsets), "app_label": opts.app_label, "add": False, "change": True, "has_add_permission": self.has_add_permission(request), "has_change_permission": self.has_change_permission(request, obj), "has_delete_permission": self.has_delete_permission(request, obj), "has_file_field": True, "has_absolute_url": getattr(self.model, 'get_absolute_url', False), "ordered_objects": opts.get_ordered_objects(), "form_url": mark_safe(request.path), "opts": opts, "content_type_id": ContentType.objects.get_for_model(self.model).id, "save_as": False, "save_on_top": self.save_on_top, "changelist_url": reverse("admin:%s_%s_changelist" % (opts.app_label, opts.module_name)), "change_url": reverse("admin:%s_%s_change" % (opts.app_label, opts.module_name), args=(obj.pk,)), "history_url": reverse("admin:%s_%s_history" % (opts.app_label, opts.module_name), args=(obj.pk,)), "recoverlist_url": reverse("admin:%s_%s_recoverlist" % (opts.app_label, opts.module_name))}) # Render the form. if revert: form_template = self.revision_form_template elif recover: form_template = self.recover_form_template else: assert False return render_to_response(form_template, context, template.RequestContext(request))
def get_field_from_model_by_name(model_class, field_name): """ Get a field by name from a model class without messing with the app cache. """ return first_match(lambda x: x if x.name == field_name else None, model_class._meta.fields)
def render_revision_form(self, request, obj, version, context, revert=False, recover=False): """Renders the object revision form.""" model = self.model opts = model._meta object_id = obj.pk # Generate the model form. ModelForm = self.get_form(request, obj) formsets = [] if request.method == "POST": # This section is copied directly from the model admin change view # method. Maybe one day there will be a hook for doing this better. form = ModelForm(request.POST, request.FILES, instance=obj, initial=self.get_revision_form_data( request, obj, version)) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=True) else: form_validated = False new_object = obj prefixes = {} for FormSet, inline in zip(self.get_formsets(request, new_object), self.inline_instances): 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, prefix=prefix, queryset=inline.queryset(request)) # _ _ _ ____ ___ ____ _ _ ____ _ _ ___ # | | | |__| | | |__| | | | | | # |_|_| | | | |___ | | |__| |__| | # this is not copy pasted: # Strip extra empty forms from the formset. empty_forms = [] post_keys = request.POST.keys() for f in formset.forms: # the forms that can be removed, are not in the request.POST # we can find them by their prefix matches_prefix = lambda var: var.find(f.prefix ) == 0 or None if first_match(matches_prefix, post_keys) is None: empty_forms.append(f) else: # the form must be cleaned, which they aren't yet because # we just created them f.full_clean() # modify form settings of formset. num_forms = formset.total_form_count() - len(empty_forms) formset.forms = filter(lambda x: x not in empty_forms, formset.forms) formset.total_form_count = lambda: num_forms # end of non copy pasted piece # Add this hacked formset to the form. formsets.append(formset) if all_valid(formsets) 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) # _ _ _ ____ ___ ____ _ _ ____ _ _ ___ # | | | |__| | | |__| | | | | | # |_|_| | | | |___ | | |__| |__| | # this is not copy pasted: self.update_draft(version, request) change_message = _(u"Publisher message %(datetime)s") % { "datetime": format(version.revision.date_created, _(settings.DATETIME_FORMAT)) } self.log_change(request, new_object, change_message) self.message_user( request, _(u'%(model)s "%(name)s" publisher message.') % { "model": force_unicode(opts.verbose_name), "name": unicode(obj) }) # end of not copy pasted code # Redirect to the model change form. if revert: return HttpResponseRedirect("../../") elif recover: return HttpResponseRedirect("../../%s/" % object_id) else: assert False else: # This is a mutated version of the code in the standard model admin # change_view. Once again, a hook for this kind of functionality # would be nice. Unfortunately, it results in doubling the number # of queries required to construct the formets. form = ModelForm(instance=obj, initial=self.get_revision_form_data( request, obj, version)) prefixes = {} revision_versions = version.revision.version_set.all() for FormSet, inline in zip(self.get_formsets(request, obj), self.inline_instances): # This code is standard for creating the formset. 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=obj, prefix=prefix, queryset=inline.queryset(request)) # Now we hack it to push in the data from the revision! try: fk_name = FormSet.fk.name except AttributeError: # This is a GenericInlineFormset, or similar. fk_name = FormSet.ct_fk_field.name # _ _ _ ____ ___ ____ _ _ ____ _ _ ___ # | | | |__| | | |__| | | | | | # |_|_| | | | |___ | | |__| |__| | # this is not copy pasted: related_versions = [ (related_version.object_id, related_version) for related_version in revision_versions if ContentType.objects.get_for_id( related_version.content_type_id).model_class() == FormSet.model and unicode(related_version.field_dict[fk_name]) == unicode(object_id) ] # all items that do not have their id filled in must stay. # if they do in fact have an id, we only want the last one, # no duplicates. related_versions = [(key, value) for (key, value) in related_versions if key == 'None'] + \ dict([(key, value) for (key, value) in related_versions if key != 'None']).items() initial = [] for related_obj in formset.queryset: related_versions_dict = dict(related_versions) if unicode(related_obj.pk) in related_versions_dict: initial.append( related_versions_dict.pop(unicode( related_obj.pk)).field_dict) else: initial_data = model_to_dict(related_obj) initial_data["DELETE"] = True initial.append(initial_data) for (key, related_version) in related_versions: initial_row = related_version.field_dict try: del initial_row["id"] except KeyError: # when multiple inlines with the same model but a different # querysets are on a page, it could happen that we allready # deleted the id. pass # we didn't convert related_versions to a dict so there can be # duplicate keys in the thingy if not initial_row in initial: initial.append(initial_row) # end of non copy pasted piece # Reconstruct the forms with the new revision data. formset.initial = initial formset.forms = [ formset._construct_form(n) for n in xrange(len(initial)) ] # Add this hacked formset to the form. formsets.append(formset) # Generate admin form helper. adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields, self.get_readonly_fields(request, obj), model_admin=self) media = self.media + adminForm.media # Generate formset helpers. inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request, obj)) readonly = list(inline.get_readonly_fields(request, obj)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets, readonly, model_admin=self) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media # Generate the context. context.update({ "adminform": adminForm, "object_id": object_id, "original": obj, "is_popup": False, "media": mark_safe(media), "inline_admin_formsets": inline_admin_formsets, "errors": helpers.AdminErrorList(form, formsets), "app_label": opts.app_label, "add": False, "change": True, "has_add_permission": self.has_add_permission(request), "has_change_permission": self.has_change_permission(request, obj), "has_delete_permission": self.has_delete_permission(request, obj), "has_file_field": True, "has_absolute_url": getattr(self.model, 'get_absolute_url', False), "ordered_objects": opts.get_ordered_objects(), "form_url": mark_safe(request.path), "opts": opts, "content_type_id": ContentType.objects.get_for_model(self.model).id, "save_as": False, "save_on_top": self.save_on_top, "changelist_url": reverse("admin:%s_%s_changelist" % (opts.app_label, opts.module_name)), "change_url": reverse("admin:%s_%s_change" % (opts.app_label, opts.module_name), args=(obj.pk, )), "history_url": reverse("admin:%s_%s_history" % (opts.app_label, opts.module_name), args=(obj.pk, )), "recoverlist_url": reverse("admin:%s_%s_recoverlist" % (opts.app_label, opts.module_name)) }) # Render the form. if revert: form_template = self.revision_form_template elif recover: form_template = self.recover_form_template else: assert False return render_to_response(form_template, context, template.RequestContext(request))