Alex Ulianytskyi avatar Alex Ulianytskyi committed 8ff0ff9

Добавлены функция сохранения форм, наборов форм и инлайновых наборов из админки django, поддержка мультиязычных форм

Comments (0)

Files changed (3)

+# -*- coding: utf-8 -*-
+from django.forms.formsets import all_valid
+
+def get_formsets(request, model_admin, obj=None):
+    formsets = []
+    prefixes = {}
+    for FormSet in model_admin.get_formsets(request, obj):
+        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)
+        formsets.append(formset)
+    return formsets
+
+def save_form_and_formsets(request, model_admin, ModelForm=None, obj=None):
+    formsets = []
+    if ModelForm is None:
+        ModelForm = model_admin.get_form(request, obj)
+
+    form_validated = None
+    
+    if request.method == 'POST':
+        form = ModelForm(request.POST, request.FILES, instance=obj)
+        if form.is_valid():
+            form_validated = True
+            new_object = model_admin.save_form(request, form, change=True)
+        else:
+            form_validated = False
+            new_object = obj
+        prefixes = {}
+        for FormSet in model_admin.get_formsets(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, prefix=prefix)
+            formsets.append(formset)
+
+        if all_valid(formsets) and form_validated:
+            model_admin.save_model(request, new_object, form, change=True)
+            form.save_m2m()
+            for formset in formsets:
+                model_admin.save_formset(request, form, formset, change=True)
+            #FIXME: redirect
+
+    else:
+        form = ModelForm(instance=obj)
+        formsets = get_formsets(request, model_admin, obj)
+        new_object=obj
+    return (form, formsets, form_validated, new_object)
+# -*- coding: utf-8 -*-
+from django.contrib.admin import helpers
+from django_utils.admin import get_formsets
+from multilingual.languages import get_default_language
+
+def get_inline_admin_formsets(request, model_admin, ModelForm=None, obj=None):
+    if ModelForm is None:
+        ModelForm = model_admin.get_form(request, obj)
+
+    formsets = get_formsets(request, model_admin, obj)
+    form = ModelForm(instance=obj)
+    
+    inline_admin_formsets = []
+    for inline, formset in zip(model_admin.inline_instances, formsets):
+        fieldsets = list(inline.get_fieldsets(request, obj))
+        inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets)
+        inline_admin_formsets.append(inline_admin_formset)
+
+    # I'm overriding render_change_form to inject information
+    # about prepopulated_fields
+
+    trans_model = model_admin.model._meta.translation_model
+    trans_fields = trans_model._meta.translated_fields
+
+    def field_name_to_fake_field(field_name):
+        """
+            Return something that looks like a form field enough to
+            fool prepopulated_fields_js.html
+
+            For field_names of real fields in model_admin.model this actually
+            returns a real form field.
+            """
+        try:
+            field, language_id = trans_fields[field_name]
+            if language_id is None:
+                language_id = get_default_language()
+
+            # TODO: we have this mapping between language_id and
+            # field id in two places -- here and in
+            # edit_inline_translations_newforms.html
+            # It is not DRY.
+            field_idx = language_id - 1
+            ret = {'auto_id': 'id_translations-%d-%s' % (field_idx, field.name)
+                }
+        except:
+            ret = form[field_name]
+        return ret
+
+#    prepopulated_fields = [{
+#        'field': field_name_to_fake_field(field_name),
+#        'dependencies': [field_name_to_fake_field(f) for f in dependencies]
+#    } for field_name, dependencies in model_admin._dm_prepopulated_fields.items()]
+    return inline_admin_formsets
 from django.views.generic.create_update import apply_extra_context
 from django.views.generic.create_update import get_model_and_form_class
 from django.views.generic.create_update import lookup_object
+from django_utils.admin import save_form_and_formsets
+from django_utils.translation import get_inline_admin_formsets
 
 def redirect(post_save_redirect, obj):
     """
         slug_field='slug', template_name=None, template_loader=loader,
         extra_context=None, post_save_redirect=None, login_required=False,
         context_processors=None, template_object_name='object',
-        form_class=None):
+        form_class=None, model_admin=None):
     """
     Create or update object
 
     if obj is None and (object_id is not None or slug is not None):
         obj = lookup_object(model, object_id, slug, slug_field)
 
-    if request.method == 'POST':
-        form = form_class(request.POST, request.FILES, instance=obj)
-        if form.is_valid():
-            obj = form.save()
-            if request.user.is_authenticated():
-                request.user.message_set.create(message=ugettext("The %(verbose_name)s was updated successfully.") % {"verbose_name": model._meta.verbose_name})
+    context = {template_object_name: obj}
+    formsets = []
+
+    if model_admin is not None:
+        inline_admin_formsets = get_inline_admin_formsets(request, model_admin, form_class, obj)
+        context.update({'inline_admin_formsets': inline_admin_formsets})
+        form, formsets, form_validated, obj = save_form_and_formsets(request, model_admin, form_class, obj)
+        if form_validated:
             return redirect(post_save_redirect, obj)
     else:
-        form = form_class(instance=obj)
+        if request.method == 'POST':
+            form = form_class(request.POST, request.FILES, instance=obj)
+            if form.is_valid():
+                obj = form.save()
+                if request.user.is_authenticated():
+                    request.user.message_set.create(message=ugettext("The %(verbose_name)s was updated successfully.") % {"verbose_name": model._meta.verbose_name})
+                return redirect(post_save_redirect, obj)
+        else:
+            form = form_class(instance=obj)
 
     if not template_name:
         template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower())
     t = template_loader.get_template(template_name)
-    c = RequestContext(request, {
-                       'form': form,
-                       template_object_name: obj,
-                       }, context_processors)
+    context.update({'form': form, 'formsets': formsets})
+    c = RequestContext(request,
+                       context,
+                       context_processors)
     apply_extra_context(extra_context, c)
     response = HttpResponse(t.render(c))
     if obj is not None:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.