def mass_update(modeladmin, request, queryset):
    """
        mass update queryset
    """

    def not_required(field, **kwargs):
        """ force all fields as not required"""
        kwargs['required'] = False
        return field.formfield(**kwargs)

    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label.lower(), get_permission_codename('adminactions_massupdate', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action'))
        return

    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action='mass_update',
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    # Allows to specified a custom mass update Form in the ModelAdmin
    mass_update_form = getattr(modeladmin, 'mass_update_form', MassUpdateForm)

    MForm = modelform_factory(modeladmin.model, form=mass_update_form, formfield_callback=not_required)
    grouped = defaultdict(lambda: [])
    selected_fields = []
    initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
               'select_across': request.POST.get('select_across') == '1',
               'action': 'mass_update'}

    if 'apply' in request.POST:
        form = MForm(request.POST)
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action='mass_update',
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return HttpResponseRedirect(request.get_full_path())

            need_transaction = form.cleaned_data.get('_unique_transaction', False)
            validate = form.cleaned_data.get('_validate', False)
            clean = form.cleaned_data.get('_clean', False)

            updated = 0
            errors = {}
            if validate:
                if need_transaction:
                    transaction.enter_transaction_management()
                    transaction.managed(True)
                for record in queryset:
                    for field_name, value_or_func in form.cleaned_data.items():
                        if callable(value_or_func):
                            old_value = getattr(record, field_name)
                            setattr(record, field_name, value_or_func(old_value))
                        else:
                            setattr(record, field_name, value_or_func)
                    try:
                        if clean:
                            record.clean()
                        record.save()
                    except IntegrityError as e:
                        errors[record.pk] = str(e)
                        if need_transaction:
                            transaction.rollback()
                            updated = 0
                            break
                    else:
                        updated += 1
                if updated:
                    messages.info(request, _("Updated %s records") % updated)
                if len(errors):
                    messages.error(request, "%s records not updated due errors" % len(errors))
                try:
                    adminaction_end.send(sender=modeladmin.model,
                                         action='mass_update',
                                         request=request,
                                         queryset=queryset,
                                         modeladmin=modeladmin,
                                         form=form,
                                         errors=errors,
                                         updated=updated)
                    if need_transaction:
                        transaction.commit()
                except ActionInterrupted:
                    if need_transaction:
                        transaction.rollback()
                finally:
                    if need_transaction:
                        transaction.leave_transaction_management()

            else:
                values = {}
                for field_name, value in form.cleaned_data.items():
                    if isinstance(form.fields[field_name], ModelMultipleChoiceField):
                        messages.error(request, "Unable no mass update ManyToManyField without 'validate'")
                        return HttpResponseRedirect(request.get_full_path())
                    elif callable(value):
                        messages.error(request, "Unable no mass update using operators without 'validate'")
                        return HttpResponseRedirect(request.get_full_path())
                    elif field_name not in ['_selected_action', '_validate', 'select_across', 'action']:
                        values[field_name] = value
                queryset.update(**values)

            return HttpResponseRedirect(request.get_full_path())
    else:
        initial.update({'action': 'mass_update', '_validate': 1})
        #form = MForm(initial=initial)
        prefill_with = request.POST.get('prefill-with', None)
        prefill_instance = None
        try:
            # Gets the instance directly from the queryset for data security
            prefill_instance = queryset.get(pk=prefill_with)
        except ObjectDoesNotExist:
            pass

        form = MForm(initial=initial, instance=prefill_instance)

    for el in queryset.all()[:10]:
        for f in modeladmin.model._meta.fields:
            if f.name not in form._no_sample_for:
                if hasattr(f, 'flatchoices') and f.flatchoices:
                    grouped[f.name] = dict(getattr(f, 'flatchoices')).values()
                elif hasattr(f, 'choices') and f.choices:
                    grouped[f.name] = dict(getattr(f, 'choices')).values()
                elif isinstance(f, df.BooleanField):
                    grouped[f.name] = [True, False]
                else:
                    value = getattr(el, f.name)
                    if value is not None and value not in grouped[f.name]:
                        grouped[f.name].append(value)
                    initial[f.name] = initial.get(f.name, value)

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, [], model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime.date) else str(obj)
    tpl = 'adminactions/mass_update.html'
    ctx = {'adminform': adminForm,
           'form': form,
           'title': u"Mass update %s" % force_unicode(modeladmin.opts.verbose_name_plural),
           'grouped': grouped,
           'fieldvalues': json.dumps(grouped, default=dthandler),
           'change': True,
           'selected_fields': selected_fields,
           'is_popup': False,
           'save_as': False,
           'has_delete_permission': False,
           'has_add_permission': False,
           'has_change_permission': True,
           'opts': modeladmin.model._meta,
           'app_label': modeladmin.model._meta.app_label,
           #           'action': 'mass_update',
           #           'select_across': request.POST.get('select_across')=='1',
           'media': mark_safe(media),
           'selection': queryset}

    return render_to_response(tpl, RequestContext(request, ctx))
示例#2
0
def merge(modeladmin, request, queryset):
    """
    Merge two model instances. Move all foreign keys.

    """

    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(
        opts.app_label.lower(),
        get_permission_codename('adminactions_merge', opts))
    if not request.user.has_perm(perm):
        messages.error(
            request,
            _('Sorry you do not have rights to execute this action (%s)' %
              perm))
        return

    def raw_widget(field, **kwargs):
        """ force all fields as not required"""
        kwargs['widget'] = TextInput({'class': 'raw-value'})
        return field.formfield(**kwargs)

    merge_form = getattr(modeladmin, 'merge_form', MergeForm)
    MForm = modelform_factory(modeladmin.model,
                              form=merge_form,
                              exclude=('pk', ),
                              formfield_callback=raw_widget)
    OForm = modelform_factory(modeladmin.model,
                              exclude=('pk', ),
                              formfield_callback=raw_widget)

    tpl = 'adminactions/merge.html'
    # transaction_supported = model_supports_transactions(modeladmin.model)
    ctx = {
        '_selected_action':
        request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
        'transaction_supported':
        'Un',
        'select_across':
        request.POST.get('select_across') == '1',
        'action':
        request.POST.get('action'),
        'fields': [
            f for f in queryset.model._meta.fields
            if not f.primary_key and f.editable
        ],
        'app_label':
        queryset.model._meta.app_label,
        'result':
        '',
        'opts':
        queryset.model._meta
    }

    if 'preview' in request.POST:
        master = queryset.get(pk=request.POST.get('master_pk'))
        original = clone_instance(master)
        other = queryset.get(pk=request.POST.get('other_pk'))
        formset = formset_factory(OForm)(
            initial=[model_to_dict(master),
                     model_to_dict(other)])
        with transaction.nocommit():
            form = MForm(request.POST, instance=master)
            other.delete()
            form_is_valid = form.is_valid()
        if form_is_valid:
            ctx.update({'original': original})
            tpl = 'adminactions/merge_preview.html'
        else:
            master = queryset.get(pk=request.POST.get('master_pk'))
            other = queryset.get(pk=request.POST.get('other_pk'))

    elif 'apply' in request.POST:
        master = queryset.get(pk=request.POST.get('master_pk'))
        other = queryset.get(pk=request.POST.get('other_pk'))
        formset = formset_factory(OForm)(
            initial=[model_to_dict(master),
                     model_to_dict(other)])
        with transaction.nocommit():
            form = MForm(request.POST, instance=master)
            stored_pk = other.pk
            other.delete()
            ok = form.is_valid()
            other.pk = stored_pk
        if ok:
            if form.cleaned_data['dependencies'] == MergeForm.DEP_MOVE:
                related = api.ALL_FIELDS
            else:
                related = None
            fields = form.cleaned_data['field_names']
            api.merge(master,
                      other,
                      fields=fields,
                      commit=True,
                      related=related)
            return HttpResponseRedirect(request.path)
        else:
            messages.error(request, form.errors)
    else:
        try:
            master, other = queryset.all()
            # django 1.4 need to remove the trailing milliseconds
            for field in master._meta.fields:
                if isinstance(field, models.DateTimeField):
                    for target in (master, other):
                        raw_value = getattr(target, field.name)
                        fixed_value = datetime(raw_value.year, raw_value.month,
                                               raw_value.day, raw_value.hour,
                                               raw_value.minute,
                                               raw_value.second)
                        setattr(target, field.name, fixed_value)
        except ValueError:
            messages.error(request, _('Please select exactly 2 records'))
            return

        initial = {
            '_selected_action':
            request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
            'select_across': 0,
            'generic': MergeForm.GEN_IGNORE,
            'dependencies': MergeForm.DEP_MOVE,
            'action': 'merge',
            'master_pk': master.pk,
            'other_pk': other.pk
        }
        formset = formset_factory(OForm)(
            initial=[model_to_dict(master),
                     model_to_dict(other)])
        form = MForm(initial=initial, instance=master)

    adminForm = helpers.AdminForm(form,
                                  modeladmin.get_fieldsets(request), {}, [],
                                  model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    ctx.update({
        'adminform':
        adminForm,
        'formset':
        formset,
        'media':
        mark_safe(media),
        'title':
        u"Merge %s" % force_unicode(modeladmin.opts.verbose_name_plural),
        'master':
        master,
        'other':
        other
    })
    return render_to_response(tpl, RequestContext(request, ctx))
示例#3
0
def export_delete_tree(modeladmin, request, queryset):  # noqa
    """
    Export as fixture selected queryset and all the records that belong to.
    That mean that dump what will be deleted if the queryset was deleted
    """
    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label, get_permission_codename('adminactions_export', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action'))
        return
    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action='export_delete_tree',
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
               'select_across': request.POST.get('select_across') == '1',
               'action': get_action(request),

               'serializer': 'json',
               'indent': 4}

    if 'apply' in request.POST:
        form = FixtureOptions(request.POST)
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action='export_delete_tree',
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return
            try:
                collect_related = form.cleaned_data.get('add_foreign_keys')
                using = router.db_for_write(modeladmin.model)

                c = Collector(using)
                c.collect(queryset, collect_related=collect_related)
                data = []
                for model, instances in list(c.data.items()):
                    data.extend(instances)
                adminaction_end.send(sender=modeladmin.model,
                                     action='export_delete_tree',
                                     request=request,
                                     queryset=queryset,
                                     modeladmin=modeladmin,
                                     form=form)
                if hasattr(modeladmin, 'get_export_delete_tree_filename'):
                    filename = modeladmin.get_export_delete_tree_filename(request, queryset)
                else:
                    filename = None
                return _dump_qs(form, queryset, data, filename)
            except AttributeError as e:
                messages.error(request, str(e))
                return HttpResponseRedirect(request.path)
    else:
        form = FixtureOptions(initial=initial)

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    tpl = 'adminactions/export_fixture.html'
    ctx = {'adminform': adminForm,
           'change': True,
           'action_short_description': export_delete_tree.short_description,
           'title': u"%s (%s)" % (
               export_delete_tree.short_description.capitalize(),
               modeladmin.opts.verbose_name_plural,
           ),
           'is_popup': False,
           'save_as': False,
           'has_delete_permission': False,
           'has_add_permission': False,
           'has_change_permission': True,
           'queryset': queryset,
           'opts': queryset.model._meta,
           'app_label': queryset.model._meta.app_label,
           'media': mark_safe(media)}
    if django.VERSION[:2] > (1, 7):
        ctx.update(modeladmin.admin_site.each_context(request))
    else:
        ctx.update(modeladmin.admin_site.each_context())
    return render_to_response(tpl, RequestContext(request, ctx))
示例#4
0
def base_export(modeladmin, request, queryset, title, impl,  # noqa
                name, action_short_description, template, form_class, ):
    """
        export a queryset to csv file
    """
    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label, get_permission_codename('adminactions_export', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action'))
        return

    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action=name,
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    cols = [(f.name, f.verbose_name) for f in queryset.model._meta.fields]
    initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
               'select_across': request.POST.get('select_across') == '1',
               'action': get_action(request),
               'columns': [x for x, v in cols]}
    if initial["action"] == "export_as_csv":
        initial.update(getattr(
            settings, "ADMINACTIONS_CSV_OPTIONS_DEFAULT", {}))

    if 'apply' in request.POST:
        form = form_class(request.POST)
        form.fields['columns'].choices = cols
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action=name,
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return

            if hasattr(modeladmin, 'get_%s_filename' % name):
                filename = modeladmin.get_export_as_csv_filename(request, queryset)
            else:
                filename = None
            try:
                response = impl(queryset,
                                fields=form.cleaned_data['columns'],
                                header=form.cleaned_data.get('header', False),
                                filename=filename,
                                options=form.cleaned_data)
            except Exception as e:
                messages.error(request, "Error: (%s)" % str(e))
            else:
                adminaction_end.send(sender=modeladmin.model,
                                     action=name,
                                     request=request,
                                     queryset=queryset,
                                     modeladmin=modeladmin,
                                     form=form)
                return response
    else:
        form = form_class(initial=initial)
        form.fields['columns'].choices = cols

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, [], model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    # tpl = 'adminactions/export_csv.html'
    ctx = {'adminform': adminForm,
           'change': True,
           'action_short_description': action_short_description,
           'title': title,
           'is_popup': False,
           'save_as': False,
           'has_delete_permission': False,
           'has_add_permission': False,
           'has_change_permission': True,
           'queryset': queryset,
           'opts': queryset.model._meta,
           'app_label': queryset.model._meta.app_label,
           'media': mark_safe(media)}
    if django.VERSION[:2] > (1, 7):
        ctx.update(modeladmin.admin_site.each_context(request))
    else:
        ctx.update(modeladmin.admin_site.each_context())
    return render_to_response(template, RequestContext(request, ctx))
示例#5
0
def export_as_fixture(modeladmin, request, queryset):
    initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
               'select_across': request.POST.get('select_across') == '1',
               'action': request.POST.get('action'),
               'serializer': 'json',
               'indent': 4}
    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label.lower(), get_permission_codename('adminactions_export', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action (%s)' % perm))
        return

    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action='export_as_fixture',
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    if 'apply' in request.POST:
        form = FixtureOptions(request.POST)
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action='export_as_fixture',
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return
            try:
                _collector = ForeignKeysCollector if form.cleaned_data.get('add_foreign_keys') else FlatCollector
                c = _collector(None)
                c.collect(queryset)
                adminaction_end.send(sender=modeladmin.model,
                                     action='export_as_fixture',
                                     request=request,
                                     queryset=queryset,
                                     modeladmin=modeladmin,
                                     form=form)

                if hasattr(modeladmin, 'get_export_as_fixture_filename'):
                    filename = modeladmin.get_export_as_fixture_filename(request, queryset)
                else:
                    filename = None
                return _dump_qs(form, queryset, c.data, filename)
            except AttributeError as e:
                messages.error(request, str(e))
                return HttpResponseRedirect(request.path)
    else:
        form = FixtureOptions(initial=initial)

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    tpl = 'adminactions/export_fixture.html'
    ctx = {'adminform': adminForm,
           'change': True,
           'title': _('Export as Fixture'),
           'is_popup': False,
           'save_as': False,
           'has_delete_permission': False,
           'has_add_permission': False,
           'has_change_permission': True,
           'queryset': queryset,
           'opts': queryset.model._meta,
           'app_label': queryset.model._meta.app_label,
           'media': mark_safe(media)}
    return render_to_response(tpl, RequestContext(request, ctx))
示例#6
0
def mass_update(modeladmin, request, queryset):  # noqa
    """
        mass update queryset
    """
    def not_required(field, **kwargs):
        """ force all fields as not required"""
        kwargs['required'] = False
        return field.formfield(**kwargs)

    def _doit():
        errors = {}
        updated = 0
        for record in queryset:
            for field_name, value_or_func in list(form.cleaned_data.items()):
                if callable(value_or_func):
                    old_value = getattr(record, field_name)
                    setattr(record, field_name, value_or_func(old_value))
                else:
                    setattr(record, field_name, value_or_func)
            if clean:
                record.clean()
            record.save()
            updated += 1
        if updated:
            messages.info(request, _("Updated %s records") % updated)

        if len(errors):
            messages.error(request,
                           "%s records not updated due errors" % len(errors))
        adminaction_end.send(sender=modeladmin.model,
                             action='mass_update',
                             request=request,
                             queryset=queryset,
                             modeladmin=modeladmin,
                             form=form,
                             errors=errors,
                             updated=updated)

    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(
        opts.app_label.lower(),
        get_permission_codename('adminactions_massupdate', opts))
    if not request.user.has_perm(perm):
        messages.error(
            request, _('Sorry you do not have rights to execute this action'))
        return

    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action='mass_update',
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    # Allows to specified a custom mass update Form in the ModelAdmin
    mass_update_form = getattr(modeladmin, 'mass_update_form', MassUpdateForm)

    MForm = modelform_factory(modeladmin.model,
                              form=mass_update_form,
                              exclude=('pk', ),
                              formfield_callback=not_required)
    grouped = defaultdict(lambda: [])
    selected_fields = []
    initial = {
        '_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
        'select_across': request.POST.get('select_across') == '1',
        'action': 'mass_update'
    }

    if 'apply' in request.POST:
        form = MForm(request.POST)
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action='mass_update',
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return HttpResponseRedirect(request.get_full_path())

            # need_transaction = form.cleaned_data.get('_unique_transaction', False)
            validate = form.cleaned_data.get('_validate', False)
            clean = form.cleaned_data.get('_clean', False)

            if validate:
                with compat.atomic():
                    _doit()

            else:
                values = {}
                for field_name, value in list(form.cleaned_data.items()):
                    if isinstance(form.fields[field_name],
                                  ModelMultipleChoiceField):
                        messages.error(
                            request,
                            "Unable no mass update ManyToManyField without 'validate'"
                        )
                        return HttpResponseRedirect(request.get_full_path())
                    elif callable(value):
                        messages.error(
                            request,
                            "Unable no mass update using operators without 'validate'"
                        )
                        return HttpResponseRedirect(request.get_full_path())
                    elif field_name not in [
                            '_selected_action', '_validate', 'select_across',
                            'action', '_unique_transaction', '_clean'
                    ]:
                        values[field_name] = value
                queryset.update(**values)

            return HttpResponseRedirect(request.get_full_path())
    else:
        initial.update({'action': 'mass_update', '_validate': 1})
        # form = MForm(initial=initial)
        prefill_with = request.POST.get('prefill-with', None)
        prefill_instance = None
        try:
            # Gets the instance directly from the queryset for data security
            prefill_instance = queryset.get(pk=prefill_with)
        except ObjectDoesNotExist:
            pass

        form = MForm(initial=initial, instance=prefill_instance)

    for el in queryset.all()[:10]:
        for f in modeladmin.model._meta.fields:
            if f.name not in form._no_sample_for:
                if hasattr(f, 'flatchoices') and f.flatchoices:
                    grouped[f.name] = list(
                        dict(getattr(f, 'flatchoices')).values())
                elif hasattr(f, 'choices') and f.choices:
                    grouped[f.name] = list(
                        dict(getattr(f, 'choices')).values())
                elif isinstance(f, df.BooleanField):
                    grouped[f.name] = [True, False]
                else:
                    value = getattr(el, f.name)
                    if value is not None and value not in grouped[f.name]:
                        grouped[f.name].append(value)
                    initial[f.name] = initial.get(f.name, value)

    adminForm = helpers.AdminForm(form,
                                  modeladmin.get_fieldsets(request), {}, [],
                                  model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime.date
                                                          ) else str(obj)
    tpl = 'adminactions/mass_update.html'
    ctx = {
        'adminform':
        adminForm,
        'form':
        form,
        'title':
        u"Mass update %s" % smart_text(modeladmin.opts.verbose_name_plural),
        'grouped':
        grouped,
        'fieldvalues':
        json.dumps(grouped, default=dthandler),
        'change':
        True,
        'selected_fields':
        selected_fields,
        'is_popup':
        False,
        'save_as':
        False,
        'has_delete_permission':
        False,
        'has_add_permission':
        False,
        'has_change_permission':
        True,
        'opts':
        modeladmin.model._meta,
        'app_label':
        modeladmin.model._meta.app_label,
        # 'action': 'mass_update',
        # 'select_across': request.POST.get('select_across')=='1',
        'media':
        mark_safe(media),
        'selection':
        queryset
    }

    return render_to_response(tpl, RequestContext(request, ctx))
示例#7
0
def base_export(modeladmin, request, queryset, title, impl, name, template, form_class, ):
    """
        export a queryset to csv file
    """
    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label.lower(), get_permission_codename('adminactions_export', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action (%s)' % perm))
        return

    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action=name,
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    cols = [(f.name, f.verbose_name) for f in queryset.model._meta.fields]
    initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
               'select_across': request.POST.get('select_across') == '1',
               'action': request.POST.get('action'),
               'columns': [x for x, v in cols]}
    # initial.update(csv_options_default)

    if 'apply' in request.POST:
        form = form_class(request.POST)
        form.fields['columns'].choices = cols
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action=name,
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return

            if hasattr(modeladmin, 'get_%s_filename' % name):
                filename = modeladmin.get_export_as_csv_filename(request, queryset)
            else:
                filename = None
            try:
                response = impl(queryset,
                                fields=form.cleaned_data['columns'],
                                header=form.cleaned_data.get('header', False),
                                filename=filename,
                                options=form.cleaned_data)
            except Exception as e:
                messages.error(request, "Error: (%s)" % str(e))
            else:
                adminaction_end.send(sender=modeladmin.model,
                                     action=name,
                                     request=request,
                                     queryset=queryset,
                                     modeladmin=modeladmin,
                                     form=form)
                return response
    else:
        form = form_class(initial=initial)
        form.fields['columns'].choices = cols

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, [], model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    # tpl = 'adminactions/export_csv.html'
    ctx = {'adminform': adminForm,
           'change': True,
           'title': title,
           'is_popup': False,
           'save_as': False,
           'has_delete_permission': False,
           'has_add_permission': False,
           'has_change_permission': True,
           'queryset': queryset,
           'opts': queryset.model._meta,
           'app_label': queryset.model._meta.app_label,
           'media': mark_safe(media)}
    return render_to_response(template, RequestContext(request, ctx))
示例#8
0
def export_delete_tree(modeladmin, request, queryset):
    """
    Export as fixture selected queryset and all the records that belong to.
    That mean that dump what will be deleted if the queryset was deleted
    """
    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label.lower(), get_permission_codename('adminactions_export', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action (%s)' % perm))
        return
    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action='export_delete_tree',
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
               'select_across': request.POST.get('select_across') == '1',
               'action': request.POST.get('action'),
               'serializer': 'json',
               'indent': 4}

    if 'apply' in request.POST:
        form = FixtureOptions(request.POST)
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action='export_delete_tree',
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return
            try:
                collect_related = form.cleaned_data.get('add_foreign_keys')
                using = router.db_for_write(modeladmin.model)

                c = Collector(using)
                c.collect(queryset, collect_related=collect_related)
                data = []
                for model, instances in c.data.items():
                    data.extend(instances)
                adminaction_end.send(sender=modeladmin.model,
                                     action='export_delete_tree',
                                     request=request,
                                     queryset=queryset,
                                     modeladmin=modeladmin,
                                     form=form)
                if hasattr(modeladmin, 'get_export_delete_tree_filename'):
                    filename = modeladmin.get_export_delete_tree_filename(request, queryset)
                else:
                    filename = None
                return _dump_qs(form, queryset, data, filename)
            except AttributeError as e:
                messages.error(request, str(e))
                return HttpResponseRedirect(request.path)
    else:
        form = FixtureOptions(initial=initial)

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    tpl = 'adminactions/export_fixture.html'
    ctx = {'adminform': adminForm,
           'change': True,
           'title': _('Export Delete Tree'),
           'is_popup': False,
           'save_as': False,
           'has_delete_permission': False,
           'has_add_permission': False,
           'has_change_permission': True,
           'queryset': queryset,
           'opts': queryset.model._meta,
           'app_label': queryset.model._meta.app_label,
           'media': mark_safe(media)}
    return render_to_response(tpl, RequestContext(request, ctx))
def byrows_update(modeladmin, request, queryset):  # noqa
    """
        by rows update queryset

        :type modeladmin: ModelAdmin
        :type request: HttpRequest
        :type queryset: QuerySet
    """

    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label.lower(), get_permission_codename('adminactions_byrowsupdate', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action'))
        return

    class modelform(modeladmin.form):
        def __init__(self, *args, **kwargs):
            super(modeladmin.form, self).__init__(*args, **kwargs)
            if self.instance:
                readonly_fields = (modeladmin.model._meta.pk.name,) + modeladmin.get_readonly_fields(request)
                for fname in readonly_fields:
                    if fname in self.fields:
                        self.fields[fname].widget.attrs['readonly'] = 'readonly'
                        self.fields[fname].widget.attrs['class'] = 'readonly'

    fields = byrows_update_get_fields(modeladmin)

    ActionForm = modelform_factory(modeladmin.model,
                                   form=GenericActionForm,
                                   fields=fields)

    MFormSet = modelformset_factory(modeladmin.model, form=modelform, fields=fields, extra=0)

    if 'apply' in request.POST:
        actionform = ActionForm(request.POST)
        formset = MFormSet(request.POST)
        if formset.is_valid():
            formset.save()
            messages.info(request, _("Updated record(s)"))
            return HttpResponseRedirect(request.get_full_path())
    else:
        action_form_initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
                               'select_across': request.POST.get('select_across') == '1',
                               'action': 'byrows_update'}
        actionform = ActionForm(initial=action_form_initial, instance=None)
        formset = MFormSet(queryset=queryset)

    adminform = helpers.AdminForm(
        actionform,
        modeladmin.get_fieldsets(request),
        {},
        [],
        model_admin=modeladmin)

    tpl = 'adminactions/byrows_update.html'
    ctx = {
        'adminform': adminform,
        'actionform': actionform,
        'action_short_description': byrows_update.short_description,
        'title': u"%s (%s)" % (
            byrows_update.short_description.capitalize(),
            smart_text(modeladmin.opts.verbose_name_plural),
        ),
        'formset': formset,
        'opts': modeladmin.model._meta,
        'app_label': modeladmin.model._meta.app_label,
    }
    if django.VERSION[:2] > (1, 7):
        ctx.update(modeladmin.admin_site.each_context(request))
    else:
        ctx.update(modeladmin.admin_site.each_context())

    return render_to_response(tpl, RequestContext(request, ctx))
示例#10
0
def export_as_fixture(modeladmin, request, queryset):
    initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
               'select_across': request.POST.get('select_across') == '1',
               'action': request.POST.get('action'),
               'serializer': 'json',
               'indent': 4}
    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label.lower(), get_permission_codename('adminactions_export', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action (%s)' % perm))
        return

    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action='export_as_fixture',
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    if 'apply' in request.POST:
        form = FixtureOptions(request.POST)
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action='export_as_fixture',
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return
            try:
                _collector = ForeignKeysCollector if form.cleaned_data.get('add_foreign_keys') else FlatCollector
                c = _collector(None)
                c.collect(queryset)
                adminaction_end.send(sender=modeladmin.model,
                                     action='export_as_fixture',
                                     request=request,
                                     queryset=queryset,
                                     modeladmin=modeladmin,
                                     form=form)

                if hasattr(modeladmin, 'get_export_as_fixture_filename'):
                    filename = modeladmin.get_export_as_fixture_filename(request, queryset)
                else:
                    filename = None
                return _dump_qs(form, queryset, c.data, filename)
            except AttributeError as e:
                messages.error(request, str(e))
                return HttpResponseRedirect(request.path)
    else:
        form = FixtureOptions(initial=initial)

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    tpl = 'adminactions/export_fixture.html'
    ctx = {'adminform': adminForm,
           'change': True,
           'title': _('Export as Fixture'),
           'is_popup': False,
           'save_as': False,
           'has_delete_permission': False,
           'has_add_permission': False,
           'has_change_permission': True,
           'queryset': queryset,
           'opts': queryset.model._meta,
           'app_label': queryset.model._meta.app_label,
           'media': mark_safe(media)}
    return render_to_response(tpl, RequestContext(request, ctx))
示例#11
0
def merge(modeladmin, request, queryset):  # noqa
    """
    Merge two model instances. Move all foreign keys.

    """

    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label, get_permission_codename('adminactions_merge', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action (%s)' % perm))
        return

    def raw_widget(field, **kwargs):
        """ force all fields as not required"""
        kwargs['widget'] = TextInput({'class': 'raw-value'})
        return field.formfield(**kwargs)

    merge_form = getattr(modeladmin, 'merge_form', MergeForm)
    MForm = modelform_factory(modeladmin.model,
                              form=merge_form,
                              exclude=('pk', ),
                              formfield_callback=raw_widget)
    OForm = modelform_factory(modeladmin.model,
                              exclude=('pk', ),
                              formfield_callback=raw_widget)

    tpl = 'adminactions/merge.html'
    # transaction_supported = model_supports_transactions(modeladmin.model)
    ctx = {
        '_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
        'transaction_supported': 'Un',
        'select_across': request.POST.get('select_across') == '1',
        'action': request.POST.get('action'),
        'fields': [f for f in queryset.model._meta.fields if not f.primary_key and f.editable],
        'app_label': queryset.model._meta.app_label,
        'result': '',
        'opts': queryset.model._meta}

    if 'preview' in request.POST:
        master = queryset.get(pk=request.POST.get('master_pk'))
        original = clone_instance(master)
        other = queryset.get(pk=request.POST.get('other_pk'))
        formset = formset_factory(OForm)(initial=[model_to_dict(master), model_to_dict(other)])
        with transaction.nocommit():
            form = MForm(request.POST, instance=master)
            other.delete()
            form_is_valid = form.is_valid()
        if form_is_valid:
            ctx.update({'original': original})
            tpl = 'adminactions/merge_preview.html'
        else:
            master = queryset.get(pk=request.POST.get('master_pk'))
            other = queryset.get(pk=request.POST.get('other_pk'))

    elif 'apply' in request.POST:
        master = queryset.get(pk=request.POST.get('master_pk'))
        other = queryset.get(pk=request.POST.get('other_pk'))
        formset = formset_factory(OForm)(initial=[model_to_dict(master), model_to_dict(other)])
        with transaction.nocommit():
            form = MForm(request.POST, instance=master)
            stored_pk = other.pk
            other.delete()
            ok = form.is_valid()
            other.pk = stored_pk
        if ok:
            if form.cleaned_data['dependencies'] == MergeForm.DEP_MOVE:
                related = api.ALL_FIELDS
            else:
                related = None
            fields = form.cleaned_data['field_names']
            api.merge(master, other, fields=fields, commit=True, related=related)
            return HttpResponseRedirect(request.path)
        else:
            messages.error(request, form.errors)
    else:
        try:
            master, other = queryset.all()
            # django 1.4 need to remove the trailing milliseconds
            for field in master._meta.fields:
                if isinstance(field, models.DateTimeField):
                    for target in (master, other):
                        raw_value = getattr(target, field.name)
                        fixed_value = datetime(raw_value.year, raw_value.month, raw_value.day,
                                               raw_value.hour, raw_value.minute, raw_value.second)
                        setattr(target, field.name, fixed_value)
        except ValueError:
            messages.error(request, _('Please select exactly 2 records'))
            return

        initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
                   'select_across': 0,
                   'generic': MergeForm.GEN_IGNORE,
                   'dependencies': MergeForm.DEP_MOVE,
                   'action': 'merge',
                   'master_pk': master.pk,
                   'other_pk': other.pk}
        formset = formset_factory(OForm)(initial=[model_to_dict(master), model_to_dict(other)])
        form = MForm(initial=initial, instance=master)

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, [], model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    ctx.update({'adminform': adminForm,
                'formset': formset,
                'media': mark_safe(media),
                'title': u"Merge %s" % smart_text(modeladmin.opts.verbose_name_plural),
                'master': master,
                'other': other})
    return render_to_response(tpl, RequestContext(request, ctx))
def byrows_update(modeladmin, request, queryset):  # noqa
    """
        by rows update queryset

        :type modeladmin: ModelAdmin
        :type request: HttpRequest
        :type queryset: QuerySet
    """

    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(
        opts.app_label.lower(),
        get_permission_codename('adminactions_byrowsupdate', opts))
    if not request.user.has_perm(perm):
        messages.error(
            request, _('Sorry you do not have rights to execute this action'))
        return

    class modelform(modeladmin.form):
        def __init__(self, *args, **kwargs):
            super(modeladmin.form, self).__init__(*args, **kwargs)
            if self.instance:
                readonly_fields = (modeladmin.model._meta.pk.name,
                                   ) + modeladmin.get_readonly_fields(request)
                for fname in readonly_fields:
                    if fname in self.fields:
                        self.fields[fname].widget.attrs[
                            'readonly'] = 'readonly'
                        self.fields[fname].widget.attrs['class'] = 'readonly'

    fields = byrows_update_get_fields(modeladmin)

    ActionForm = modelform_factory(modeladmin.model,
                                   form=GenericActionForm,
                                   fields=fields)

    MFormSet = modelformset_factory(modeladmin.model,
                                    form=modelform,
                                    fields=fields,
                                    extra=0)

    if 'apply' in request.POST:
        actionform = ActionForm(request.POST)
        formset = MFormSet(request.POST)
        if formset.is_valid():
            formset.save()
            messages.info(request, _("Updated record(s)"))
            return HttpResponseRedirect(request.get_full_path())
    else:
        action_form_initial = {
            '_selected_action':
            request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
            'select_across': request.POST.get('select_across') == '1',
            'action': 'byrows_update'
        }
        actionform = ActionForm(initial=action_form_initial, instance=None)
        formset = MFormSet(queryset=queryset)

    adminform = helpers.AdminForm(actionform,
                                  modeladmin.get_fieldsets(request), {}, [],
                                  model_admin=modeladmin)

    tpl = 'adminactions/byrows_update.html'
    ctx = {
        'adminform':
        adminform,
        'actionform':
        actionform,
        'action_short_description':
        byrows_update.short_description,
        'title':
        u"%s (%s)" % (
            byrows_update.short_description.capitalize(),
            smart_text(modeladmin.opts.verbose_name_plural),
        ),
        'formset':
        formset,
        'opts':
        modeladmin.model._meta,
        'app_label':
        modeladmin.model._meta.app_label,
    }
    if django.VERSION[:2] > (1, 7):
        ctx.update(modeladmin.admin_site.each_context(request))
    else:
        ctx.update(modeladmin.admin_site.each_context())

    return render_to_response(tpl, RequestContext(request, ctx))
示例#13
0
def graph_queryset(modeladmin, request, queryset):  # noqa
    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label.lower(), get_permission_codename('adminactions_chart', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action'))
        return

    MForm = graph_form_factory(modeladmin.model)

    graph_type = table = None
    extra = '{}'
    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action='graph_queryset',
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    if 'apply' in request.POST:
        form = MForm(request.POST)
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action='graph_queryset',
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return
            try:
                x = form.cleaned_data['axes_x']
                # y = form.cleaned_data['axes_y']
                graph_type = form.cleaned_data['graph_type']

                field, model, direct, m2m = get_field_by_name(modeladmin.model, x)
                cc = queryset.values_list(x).annotate(Count(x)).order_by()
                if isinstance(field, ForeignKey):
                    data_labels = []
                    for value, cnt in cc:
                        data_labels.append(str(field.rel.to.objects.get(pk=value)))
                elif isinstance(field, BooleanField):
                    data_labels = [str(l) for l, v in cc]
                elif hasattr(modeladmin.model, 'get_%s_display' % field.name):
                    data_labels = []
                    for value, cnt in cc:
                        data_labels.append(smart_text(dict(field.flatchoices).get(value, value), strings_only=True))
                else:
                    data_labels = [str(l) for l, v in cc]
                data = [v for l, v in cc]

                if graph_type == 'BarChart':
                    table = [data]
                    extra = """{seriesDefaults:{renderer:$.jqplot.BarRenderer,
                                                rendererOptions: {fillToZero: true,
                                                                  barDirection: 'horizontal'},
                                                shadowAngle: -135,
                                               },
                                series:[%s],
                                axes: {yaxis: {renderer: $.jqplot.CategoryAxisRenderer,
                                                ticks: %s},
                                       xaxis: {pad: 1.05,
                                               tickOptions: {formatString: '%%d'}}
                                      }
                                }""" % (json.dumps(data_labels), json.dumps(data_labels))
                elif graph_type == 'PieChart':
                    table = [list(zip(data_labels, data))]
                    extra = """{seriesDefaults: {renderer: jQuery.jqplot.PieRenderer,
                                                rendererOptions: {fill: true,
                                                                    showDataLabels: true,
                                                                    sliceMargin: 4,
                                                                    lineWidth: 5}},
                             legend: {show: true, location: 'e'}}"""

            except Exception as e:
                messages.error(request, 'Unable to produce valid data: %s' % str(e))
            else:
                adminaction_end.send(sender=modeladmin.model,
                                     action='graph_queryset',
                                     request=request,
                                     queryset=queryset,
                                     modeladmin=modeladmin,
                                     form=form)
    elif request.method == 'POST':
        # total = queryset.all().count()
        initial = {helpers.ACTION_CHECKBOX_NAME: request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
                   'select_across': request.POST.get('select_across', 0)}
        form = MForm(initial=initial)
    else:
        initial = {helpers.ACTION_CHECKBOX_NAME: request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
                   'select_across': request.POST.get('select_across', 0)}
        form = MForm(initial=initial)

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, [], model_admin=modeladmin)
    media = modeladmin.media + adminForm.media

    ctx = {'adminform': adminForm,
           'action': 'graph_queryset',
           'opts': modeladmin.model._meta,
           'action_short_description': graph_queryset.short_description,
           'title': u"%s (%s)" % (
                graph_queryset.short_description.capitalize(),
                smart_text(modeladmin.opts.verbose_name_plural),
            ),
           'app_label': queryset.model._meta.app_label,
           'media': media,
           'extra': extra,
           'as_json': json.dumps(table),
           'graph_type': graph_type}
    if django.VERSION[:2] > (1, 7):
        ctx.update(modeladmin.admin_site.each_context(request))
    else:
        ctx.update(modeladmin.admin_site.each_context())
    return render_to_response('adminactions/charts.html', RequestContext(request, ctx))
示例#14
0
def merge(modeladmin, request, queryset):
    """
    Merge two model instances. Move all foreign keys.

    """

    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label.lower(), get_permission_codename('adminactions_merge', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action (%s)' % perm))
        return

    def raw_widget(field, **kwargs):
        """ force all fields as not required"""
        kwargs['widget'] = TextInput({'class': 'raw-value', 'readonly': 'readonly'})
        kwargs['widget'] = TextInput({'class': 'raw-value', 'size': '30'})
        return field.formfield(**kwargs)

        # Allows to specified a custom Form in the ModelAdmin

    #    MForm = getattr(modeladmin, 'merge_form', MergeForm)
    merge_form = getattr(modeladmin, 'merge_form', MergeForm)
    MForm = modelform_factory(modeladmin.model, form=merge_form, formfield_callback=raw_widget)
    OForm = modelform_factory(modeladmin.model, formfield_callback=raw_widget)
    tpl = 'adminactions/merge.html'

    ctx = {
        '_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
        'select_across': request.POST.get('select_across') == '1',
        'action': request.POST.get('action'),
        'fields': [f for f in queryset.model._meta.fields if not f.primary_key and f.editable],
        'app_label': queryset.model._meta.app_label,
        'result': '',
        'opts': queryset.model._meta}

    if 'preview' in request.POST:
        master = queryset.get(pk=request.POST.get('master_pk'))
        original = clone_instance(master)
        other = queryset.get(pk=request.POST.get('other_pk'))
        formset = formset_factory(OForm)(initial=[model_to_dict(master), model_to_dict(other)])
        with transaction.commit_manually():
            form = MForm(request.POST, instance=master)
            other.delete()
            form_is_valid = form.is_valid()
            transaction.rollback()
        if form_is_valid:
            ctx.update({'original': original})
            tpl = 'adminactions/merge_preview.html'
    elif 'apply' in request.POST:
        master = queryset.get(pk=request.POST.get('master_pk'))
        other = queryset.get(pk=request.POST.get('other_pk'))
        formset = formset_factory(OForm)(initial=[model_to_dict(master), model_to_dict(other)])
        with transaction.commit_manually():
            form = MForm(request.POST, instance=master)
            other.delete()
            if form.is_valid():
                form.save()
                transaction.commit()
                return HttpResponseRedirect(request.path)
            else:
                messages.error(request, form.errors)
                transaction.rollback()
    else:
        try:
            master, other = queryset.all()
        except ValueError:
            messages.error(request, _('Please select exactly 2 records'))
            return

        initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
                   'select_across': 0,
                   'generic': MergeForm.GEN_IGNORE,
                   'dependencies': MergeForm.DEP_MOVE,
                   'action': 'merge',
                   'master_pk': master.pk,
                   'other_pk': other.pk}
        formset = formset_factory(OForm)(initial=[model_to_dict(master), model_to_dict(other)])
        form = MForm(initial=initial, instance=master)

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, [], model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    ctx.update({'adminform': adminForm,
                'formset': formset,
                'media': mark_safe(media),
                'master': master,
                'other': other})
    return render_to_response(tpl, RequestContext(request, ctx))
示例#15
0
def graph_queryset(modeladmin, request, queryset):  # noqa
    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(
        opts.app_label.lower(),
        get_permission_codename('adminactions_chart', opts))
    if not request.user.has_perm(perm):
        messages.error(
            request, _('Sorry you do not have rights to execute this action'))
        return

    MForm = graph_form_factory(modeladmin.model)

    graph_type = table = None
    extra = '{}'
    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action='graph_queryset',
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    if 'apply' in request.POST:
        form = MForm(request.POST)
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action='graph_queryset',
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return
            try:
                x = form.cleaned_data['axes_x']
                # y = form.cleaned_data['axes_y']
                graph_type = form.cleaned_data['graph_type']

                field, model, direct, m2m = get_field_by_name(
                    modeladmin.model, x)
                cc = queryset.values_list(x).annotate(Count(x)).order_by()
                if isinstance(field, ForeignKey):
                    data_labels = []
                    for value, cnt in cc:
                        data_labels.append(
                            str(field.rel.to.objects.get(pk=value)))
                elif isinstance(field, BooleanField):
                    data_labels = [str(l) for l, v in cc]
                elif hasattr(modeladmin.model, 'get_%s_display' % field.name):
                    data_labels = []
                    for value, cnt in cc:
                        data_labels.append(
                            smart_text(dict(field.flatchoices).get(
                                value, value),
                                       strings_only=True))
                else:
                    data_labels = [str(l) for l, v in cc]
                data = [v for l, v in cc]

                if graph_type == 'BarChart':
                    table = [data]
                    extra = """{seriesDefaults:{renderer:$.jqplot.BarRenderer,
                                                rendererOptions: {fillToZero: true,
                                                                  barDirection: 'horizontal'},
                                                shadowAngle: -135,
                                               },
                                series:[%s],
                                axes: {yaxis: {renderer: $.jqplot.CategoryAxisRenderer,
                                                ticks: %s},
                                       xaxis: {pad: 1.05,
                                               tickOptions: {formatString: '%%d'}}
                                      }
                                }""" % (json.dumps(data_labels),
                                        json.dumps(data_labels))
                elif graph_type == 'PieChart':
                    table = [list(zip(data_labels, data))]
                    extra = """{seriesDefaults: {renderer: jQuery.jqplot.PieRenderer,
                                                rendererOptions: {fill: true,
                                                                    showDataLabels: true,
                                                                    sliceMargin: 4,
                                                                    lineWidth: 5}},
                             legend: {show: true, location: 'e'}}"""

            except Exception as e:
                messages.error(request,
                               'Unable to produce valid data: %s' % str(e))
            else:
                adminaction_end.send(sender=modeladmin.model,
                                     action='graph_queryset',
                                     request=request,
                                     queryset=queryset,
                                     modeladmin=modeladmin,
                                     form=form)
    elif request.method == 'POST':
        # total = queryset.all().count()
        initial = {
            helpers.ACTION_CHECKBOX_NAME:
            request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
            'select_across':
            request.POST.get('select_across', 0)
        }
        form = MForm(initial=initial)
    else:
        initial = {
            helpers.ACTION_CHECKBOX_NAME:
            request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
            'select_across':
            request.POST.get('select_across', 0)
        }
        form = MForm(initial=initial)

    adminForm = helpers.AdminForm(form,
                                  modeladmin.get_fieldsets(request), {}, [],
                                  model_admin=modeladmin)
    media = modeladmin.media + adminForm.media

    ctx = {
        'adminform':
        adminForm,
        'action':
        'graph_queryset',
        'opts':
        modeladmin.model._meta,
        'action_short_description':
        graph_queryset.short_description,
        'title':
        u"%s (%s)" % (
            graph_queryset.short_description.capitalize(),
            smart_text(modeladmin.opts.verbose_name_plural),
        ),
        'app_label':
        queryset.model._meta.app_label,
        'media':
        media,
        'extra':
        extra,
        'as_json':
        json.dumps(table),
        'graph_type':
        graph_type
    }
    if django.VERSION[:2] > (1, 7):
        ctx.update(modeladmin.admin_site.each_context(request))
    else:
        ctx.update(modeladmin.admin_site.each_context())
    return render_to_response('adminactions/charts.html',
                              RequestContext(request, ctx))