Skip to content

Commit

Permalink
Merge branch 'release/0.7'
Browse files Browse the repository at this point in the history
* release/0.7:
  bump 0.7
  add test to check mass_update success message
  updates CHANGES
  added tests
  fixes docs
  removes old test related to mass_update transactions
  update CHANGES
  removed options to enable/disable transactions during mass_update
  added option for activating get_field_display when exporting into xls
  doc and readme
  fixes issue in mass_update due wrong indentaion
  fixes and enable doctests
  open 0.7
  • Loading branch information
saxix committed Sep 20, 2014
2 parents 05fca8c + 2258c61 commit 8a12d1e
Show file tree
Hide file tree
Showing 21 changed files with 197 additions and 109 deletions.
4 changes: 2 additions & 2 deletions AUTHORS.rst
Expand Up @@ -2,8 +2,8 @@
Credits
=======

Development Lead
----------------
Author
------

* Stefano Apostolico <s.apostolico@gmail.com>

Expand Down
11 changes: 9 additions & 2 deletions CHANGES
@@ -1,3 +1,11 @@
Release 0.7
===========
* fixes issue in mass_update due wrong indentaion
* fixed :ghissue:`49`
* removed options to enable/disable transactions during mass_update.
* fixed :ghissue:`60`


Release 0.6
===========
* fixed :ghissue:`55`
Expand Down Expand Up @@ -36,8 +44,7 @@ Release 0.2
Release 0.1
===========
* new api module
* pull out core export_csv functionalites as `_export_as_csv() <api.html#adminactions.export._export_as_csv>`_
to be used by custom code
* pull out core export_csv functionalites as `_export_as_csv() <api.html#adminactions.export._export_as_csv>`_ to be used by custom code
* New exported filename callback for easy customize the filename ( see :ref:`filename_callbacks`)
* New registration shortcut `add_to_site() <api.html#adminactions.actions.add_to_site>`_
* New action: :ref:`merge`
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -40,7 +40,7 @@ test:


coverage: mkbuilddir
py.test tests --cov=adminactions --cov-report=html --cov-config=.coveragerc -vvv
py.test tests --cov=adminactions --cov-report=html --cov-config=tests/.coveragerc -vvv


ci: init-db install-deps
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Expand Up @@ -17,7 +17,7 @@ django.contrib.admin.ModelAdmin and/or django.contrib.admin.AdminSite
Please see the changelog at http://django-adminactions.readthedocs.org/en/latest/changes.html

Actions
================
=======

* Export as CSV
* Export as Excel
Expand Down
2 changes: 1 addition & 1 deletion adminactions/__init__.py
@@ -1,5 +1,5 @@
NAME = 'django-adminactions'
VERSION = __version__ = (0, 6, 0, 'final', 0)
VERSION = __version__ = (0, 7, 0, 'final', 0)
__author__ = 'sax'

import subprocess
Expand Down
3 changes: 2 additions & 1 deletion adminactions/api.py
Expand Up @@ -245,6 +245,7 @@ def _get_qs_formats(queryset):

book = xlwt.Workbook(encoding="UTF-8", style_compression=2)
sheet_name = config.pop('sheet_name')
use_display = config.get('use_display', False)

sheet = book.add_sheet(sheet_name)
style = xlwt.XFStyle()
Expand All @@ -271,7 +272,7 @@ def _get_qs_formats(queryset):
try:
value = get_field_value(row,
fieldname,
usedisplay=False,
usedisplay=use_display,
raw_callable=False)
if callable(fmt):
value = xlwt.Formula(fmt(value))
Expand Down
1 change: 1 addition & 0 deletions adminactions/forms.py
Expand Up @@ -52,6 +52,7 @@ class XLSOptions(forms.Form):
action = forms.CharField(label='', required=True, initial='', widget=forms.HiddenInput())

header = forms.BooleanField(required=False)
use_display = forms.BooleanField(required=False)
# delimiter = forms.ChoiceField(choices=zip(delimiters, delimiters), initial=',')
# quotechar = forms.ChoiceField(choices=zip(quotes, quotes), initial="'")
# quoting = forms.ChoiceField(
Expand Down
70 changes: 35 additions & 35 deletions adminactions/mass_update.py
Expand Up @@ -114,10 +114,10 @@ class MassUpdateForm(GenericActionForm):

_validate = forms.BooleanField(label='Validate',
help_text="if checked use obj.save() instead of manager.update()")
_unique_transaction = forms.BooleanField(label='Unique transaction',
required=False,
help_text="If checked create one transaction for the whole update. "
"If any record cannot be updated everything will be rolled-back")
# _unique_transaction = forms.BooleanField(label='Unique transaction',
# required=False,
# help_text="If checked create one transaction for the whole update. "
# "If any record cannot be updated everything will be rolled-back")

def __init__(self, *args, **kwargs):
super(MassUpdateForm, self).__init__(*args, **kwargs)
Expand Down Expand Up @@ -200,6 +200,34 @@ def not_required(field, **kwargs):
kwargs['required'] = False
return field.formfield(**kwargs)

def _doit():
errors = {}
updated = 0
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)
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):
Expand Down Expand Up @@ -242,40 +270,11 @@ def not_required(field, **kwargs):
messages.error(request, str(e))
return HttpResponseRedirect(request.get_full_path())

need_transaction = form.cleaned_data.get('_unique_transaction', False)
# 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:

def _doit():
errors = {}
updated = 0
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)
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)

with compat.atomic():
_doit()

Expand All @@ -288,7 +287,8 @@ def _doit():
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']:
elif field_name not in ['_selected_action', '_validate', 'select_across', 'action',
'_unique_transaction','_clean']:
values[field_name] = value
queryset.update(**values)

Expand Down
1 change: 1 addition & 0 deletions adminactions/requirements/testing.pip
Expand Up @@ -7,5 +7,6 @@ pytest
pytest-cache
pytest-cov
pytest-django
pytest-echo
selenium>=2.42.0
WebTest>=2.0.7
6 changes: 3 additions & 3 deletions adminactions/templatetags/massupdate.py
Expand Up @@ -14,8 +14,8 @@
def fields_values(d, k):
"""
>>> data = {'name1': ['value1.1', 'value1.2'], 'name2': ['value2.1', 'value2.2'], }
>>> fields_values(data, 'name1')
value1.1, value1.2
>>> print(fields_values(data, 'name1'))
value1.1,value1.2
"""
values = d.get(k, [])
return ",".join(map(str, values))
Expand All @@ -26,7 +26,7 @@ def link_fields_values(d, k):
"""
>>> data = {'name1': ['value1.1', 'value1.2'], 'name2': ['value2.1', 'value2.2'], }
>>> link_fields_values(data, 'name1')
u'<a href="#" class="fastfieldvalue name1">value1.1</a>, <a href="#" class="fastfieldvalue name1">value1.2</a>'
u'<a href="#" class="fastfieldvalue name1 value">value1.1</a>, <a href="#" class="fastfieldvalue name1 value">value1.2</a>'
"""
ret = []
for v in d.get(k, []):
Expand Down
4 changes: 2 additions & 2 deletions adminactions/utils.py
Expand Up @@ -118,12 +118,12 @@ def get_field_by_path(model, field_path):
>>> p = Permission(name='perm')
>>> f = get_field_by_path(Permission, 'content_type')
>>> print f
<django.db.models.fields.related.ForeignKey: content_type>
auth.Permission.content_type
>>> p = Permission(name='perm')
>>> f = get_field_by_path(p, 'content_type.app_label')
>>> print f
<django.db.models.fields.CharField: app_label>
contenttypes.ContentType.app_label
"""
parts = field_path.split('.')
Expand Down
28 changes: 0 additions & 28 deletions docs/source/exceptions.rst
Expand Up @@ -11,31 +11,3 @@ Exceptions

Exception raised to interrupt an action.


.. _permissions:

Permissions
===========


.. _adminactions_export:

``adminactions_export``
-----------------------
Required to execute :ref:`export_as_csv`, :ref:`export_as_fixture`, :ref:`export_delete_tree`,


.. _adminactions_massupdate:

``adminactions_massupdate``
---------------------------

Required to execute :ref:`massupdate`


.. _adminactions_merge:

``adminactions_merge``
----------------------

Required to execute :ref:`merge`
3 changes: 1 addition & 2 deletions docs/source/globals.rst
Expand Up @@ -3,9 +3,8 @@
.. _PyPI: http://pypi.python.org/
.. _virtualenv: http://virtualenv.openplans.org/

.. |standard_admin| replace:: :py:mod:`csv`
.. |app| replace:: django-adminactions


.. _app: https://github.com/saxix/django-adminactions

.. _django_admin: https://docs.djangoproject.com/en/dev/ref/contrib/admin/
2 changes: 1 addition & 1 deletion docs/source/install.rst
Expand Up @@ -10,7 +10,7 @@ Installing django-adminactions is as simple as checking out the source and addin
your project or ``PYTHONPATH``.


1. First of all follow the instruction to install `standard admin <standard_admin>`_ application,
1. First of all follow the instruction to install `django_admin`_ application,

2. Either check out django-adminactions from `GitHub`_ or to pull a release off `PyPI`_. Doing ``pip install django-adminactions`` or ``easy_install django-adminactions`` is all that should be required.

Expand Down
5 changes: 3 additions & 2 deletions docs/source/permissions.rst
@@ -1,5 +1,5 @@
.. include:: globals.rst
.. _index:
.. _permissions:

===========
Permissions
Expand Down Expand Up @@ -29,8 +29,9 @@ Required to execute :ref:`massupdate`

.. _adminactions_merge:


adminactions_merge
===================
==================

Required to execute :ref:`merge`

1 change: 1 addition & 0 deletions tests/.coveragerc
Expand Up @@ -5,6 +5,7 @@ include =
adminactions/**

omit = adminactions/__init__.py
adminactions/compat.py
tests/**

[report]
Expand Down
26 changes: 26 additions & 0 deletions tests/fixtures/demoproject.json
Expand Up @@ -50,5 +50,31 @@
"email": "s.apostolico@gmail.com",
"choices": 2
}
},
{
"pk": 2,
"model": "tests.demomodel",
"fields": {
"nullable": "bbbb",
"float": 10.1,
"generic_ip": "192.168.10.2",
"url": "https://github.com/saxix/django-adminactions",
"ip": "192.168.10.2",
"decimal": "22.2",
"time": "19:00:35",
"blank": "",
"datetime": "2013-01-01T02:18:33Z",
"char": "Pizzä ïs Gööd",
"not_editable": null,
"bigint": 333333333,
"text": "lorem ipsum",
"null_logic": true,
"logic": false,
"date": "2013-01-29",
"integer": 888888,
"unique": "unique 2",
"email": "s.apostolico@gmail.com",
"choices": 2
}
}
]
3 changes: 2 additions & 1 deletion tests/models.py
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from django.contrib.admin import ModelAdmin, site
from django.contrib.auth.models import User
from django.db import models


class DemoModel(models.Model):
char = models.CharField(max_length=255)
char = models.CharField(u'Chäř', max_length=255)
integer = models.IntegerField()
logic = models.BooleanField(default=False)
null_logic = models.NullBooleanField(default=None)
Expand Down

0 comments on commit 8a12d1e

Please sign in to comment.