Skip to content

Commit

Permalink
just some code clean
Browse files Browse the repository at this point in the history
  • Loading branch information
saxix committed Jan 1, 2016
1 parent c082822 commit 620b870
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 44 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ clean:
find . -name "*.py?" -o -name "*.orig" -prune | xargs rm -rf
find adminactions/locale -name django.mo | xargs rm -f

qa:
flake8 src/
isort -rc --check-only src/

fullclean:
rm -fr .tox .cache
Expand Down
90 changes: 50 additions & 40 deletions src/adminactions/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@

from adminactions import compat
from adminactions.templatetags.actions import get_field_value
from adminactions.utils import clone_instance, get_field_by_path
from adminactions.utils import (clone_instance, get_field_by_path,
get_filename_from_qs, get_response,)

try:
# actually supported in admin actions since django >= 1.6
Expand Down Expand Up @@ -97,7 +98,8 @@ def merge(master, other, fields=None, commit=False, m2m=None, related=None): #
all_m2m[fieldname] = []
field_object = get_field_by_path(master, fieldname)
if not isinstance(field_object, ManyToManyField):
raise ValueError('{0} is not a ManyToManyField field'.format(fieldname))
raise ValueError(
'{0} is not a ManyToManyField field'.format(fieldname))
source_m2m = getattr(other, field_object.name)
for r in source_m2m.all():
all_m2m[fieldname].append(r)
Expand All @@ -108,13 +110,15 @@ def merge(master, other, fields=None, commit=False, m2m=None, related=None): #
if related_object and isinstance(related_object.field, OneToOneField):
try:
accessor = getattr(other, name)
all_related[name] = [(related_object.field.name, accessor)]
all_related[name] = [
(related_object.field.name, accessor)]
except ObjectDoesNotExist:
pass
else:
accessor = getattr(other, name, None)
if accessor:
rel_fieldname = list(accessor.core_filters.keys())[0].split('__')[0]
rel_fieldname = list(accessor.core_filters.keys())[
0].split('__')[0]
for r in accessor.all():
all_related[name].append((rel_fieldname, r))

Expand All @@ -137,6 +141,7 @@ class Echo(object):
"""An object that implements just the write method of the file-like
interface.
"""

def write(self, value):
"""Write the value by returning it, instead of storing in a buffer."""
return value
Expand Down Expand Up @@ -166,9 +171,9 @@ def export_as_csv(queryset, fields=None, header=None, # noqa
response_class = HttpResponse

if filename is None:
filename = filename or "%s.csv" % queryset.model._meta.verbose_name_plural.lower().replace(" ", "_")
response = response_class(content_type='text/csv')
response['Content-Disposition'] = ('attachment;filename="%s"' % filename).encode('us-ascii', 'replace')
filename = filename or get_filename_from_qs(queryset, 'csv')
response = get_response("text/csv",
filename, response_class=response_class)
else:
response = out

Expand Down Expand Up @@ -213,10 +218,12 @@ def yield_rows():
value = get_field_value(obj, fieldname)
if isinstance(value, datetime.datetime):
try:
value = dateformat.format(value.astimezone(settingstime_zone), config['datetime_format'])
value = dateformat.format(value.astimezone(
settingstime_zone), config['datetime_format'])
except ValueError:
# astimezone() cannot be applied to a naive datetime
value = dateformat.format(value, config['datetime_format'])
value = dateformat.format(
value, config['datetime_format'])
elif isinstance(value, datetime.date):
value = dateformat.format(value, config['date_format'])
elif isinstance(value, datetime.time):
Expand Down Expand Up @@ -276,8 +283,10 @@ def _get_qs_formats(queryset):
if hasattr(queryset, 'model'):
for i, fieldname in enumerate(fields):
try:
f, __, __, __, = queryset.model._meta.get_field_by_name(fieldname)
fmt = xls_options_default.get(f.name, xls_options_default.get(f.__class__.__name__, 'general'))
f, __, __, __, = queryset.model._meta.get_field_by_name(
fieldname)
fmt = xls_options_default.get(
f.name, xls_options_default.get(f.__class__.__name__, 'general'))
formats[i] = fmt
except FieldDoesNotExist:
pass
Expand All @@ -288,9 +297,10 @@ def _get_qs_formats(queryset):

if out is None:
if filename is None:
filename = filename or "%s.xls" % queryset.model._meta.verbose_name_plural.lower().replace(" ", "_")
response = HttpResponse(content_type='application/vnd.ms-excel')
response['Content-Disposition'] = ('attachment;filename="%s"' % filename).encode('us-ascii', 'replace')
filename = filename or get_filename_from_qs(queryset, "xls")
response = get_response("application/vnd.ms-excel",
filename)

else:
response = out

Expand All @@ -308,11 +318,13 @@ def _get_qs_formats(queryset):
sheet = book.add_sheet(sheet_name)
style = xlwt.XFStyle()
row = 0
heading_xf = xlwt.easyxf('font:height 200; font: bold on; align: wrap on, vert centre, horiz center')
heading_xf = xlwt.easyxf(
'font:height 200; font: bold on; align: wrap on, vert centre, horiz center')
sheet.write(row, 0, u'#', style)
if header:
if not isinstance(header, (list, tuple)):
header = [force_text(f.verbose_name) for f in queryset.model._meta.fields if f.name in fields]
header = [force_text(f.verbose_name)
for f in queryset.model._meta.fields if f.name in fields]

for col, fieldname in enumerate(header, start=1):
sheet.write(row, col, fieldname, heading_xf)
Expand All @@ -338,23 +350,27 @@ def _get_qs_formats(queryset):
value = xlwt.Formula(fmt(value))
if hash(fmt) not in _styles:
if callable(fmt):
_styles[hash(fmt)] = xlwt.easyxf(num_format_str='formula')
_styles[hash(fmt)] = xlwt.easyxf(
num_format_str='formula')
else:
_styles[hash(fmt)] = xlwt.easyxf(num_format_str=fmt)

if isinstance(value, datetime.datetime):
try:
value = dateformat.format(value.astimezone(settingstime_zone), config['datetime_format'])
value = dateformat.format(value.astimezone(
settingstime_zone), config['datetime_format'])
except ValueError:
# astimezone() cannot be applied to a naive datetime
value = dateformat.format(value, config['datetime_format'])
value = dateformat.format(
value, config['datetime_format'])
if isinstance(value, (list, tuple)):
value = "".join(value)

sheet.write(rownum + 1, idx + 1, value, _styles[hash(fmt)])
except Exception as e:
# logger.warning("TODO refine this exception: %s" % e)
sheet.write(rownum + 1, idx + 1, smart_str(e), _styles[hash(fmt)])
sheet.write(rownum + 1, idx + 1,
smart_str(e), _styles[hash(fmt)])

book.save(response)
return response
Expand Down Expand Up @@ -401,25 +417,19 @@ def _get_qs_formats(queryset):
if hasattr(queryset, 'model'):
for i, fieldname in enumerate(fields):
try:
f, __, __, __, = queryset.model._meta.get_field_by_name(fieldname)
pattern = xlsxwriter_options.get(f.name, xlsxwriter_options.get(f.__class__.__name__, 'general'))
f, __, __, __, = queryset.model._meta.get_field_by_name(
fieldname)
pattern = xlsxwriter_options.get(
f.name, xlsxwriter_options.get(f.__class__.__name__, 'general'))
fmt = book.add_format({'num_format': pattern})
formats[fieldname] = fmt
except FieldDoesNotExist:
pass
# styles[i] = xlwt.easyxf(num_format_str=xls_options_default.get(col_class, 'general'))
# styles[i] = xls_options_default.get(col_class, 'general')

return formats

http_response = out is None
if out is None:
# if filename is None:
# filename = filename or "%s.xls" % queryset.model._meta.verbose_name_plural.lower().replace(" ", "_")
# response = HttpResponse(content_type='application/vnd.ms-excel')
# response['Content-Disposition'] = 'attachment;filename="%s"' % filename.encode('us-ascii', 'replace')
# out = io.BytesIO()

if six.PY2:
out = six.StringIO()
elif six.PY3:
Expand All @@ -446,7 +456,8 @@ def _get_qs_formats(queryset):
sheet.write(row, 0, force_text('#'), formats['_general_'])
if header:
if not isinstance(header, (list, tuple)):
header = [force_text(f.verbose_name)for f in queryset.model._meta.fields if f.name in fields]
header = [force_text(f.verbose_name)
for f in queryset.model._meta.fields if f.name in fields]

for col, fieldname in enumerate(header, start=1):
sheet.write(row, col, force_text(fieldname), formats['_general_'])
Expand All @@ -469,9 +480,11 @@ def _get_qs_formats(queryset):

if isinstance(value, datetime.datetime):
try:
value = dateformat.format(value.astimezone(settingstime_zone), config['datetime_format'])
value = dateformat.format(value.astimezone(
settingstime_zone), config['datetime_format'])
except ValueError:
value = dateformat.format(value, config['datetime_format'])
value = dateformat.format(
value, config['datetime_format'])

if isinstance(value, six.binary_type):
value = smart_text(value)
Expand All @@ -485,13 +498,10 @@ def _get_qs_formats(queryset):
out.seek(0)
if http_response:
if filename is None:
filename = filename or "%s.xls" % queryset.model._meta.verbose_name_plural.lower().replace(" ", "_")
response = HttpResponse(out.read(),
content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
# content_type='application/vnd.ms-excel')
# response['Content-Disposition'] = six.b('attachment;filename="%s"') % six.b(filename.encode('us-ascii', 'replace'))
response['Content-Disposition'] = six.b('attachment;filename="%s"' % filename)
return response
filename = filename or get_filename_from_qs(queryset, "xls")
return get_response("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
filename,
out.read())
return out


Expand Down
26 changes: 22 additions & 4 deletions src/adminactions/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.db import connections, models, router
# from django.db.models.fields.related import ForeignKey
from django.db.models.query import QuerySet
from django.http import HttpResponse
from django.utils.encoding import smart_text


Expand Down Expand Up @@ -77,7 +78,8 @@ def getattr_or_item(obj, name):
try:
ret = obj[name]
except KeyError:
raise AttributeError("%s object has no attribute/item '%s'" % (obj.__class__.__name__, name))
raise AttributeError(
"%s object has no attribute/item '%s'" % (obj.__class__.__name__, name))
return ret


Expand All @@ -101,7 +103,8 @@ def get_field_value(obj, field, usedisplay=True, raw_callable=False):
elif isinstance(field, models.Field):
fieldname = field.name
else:
raise ValueError('Invalid value for parameter `field`: Should be a field name or a Field instance ')
raise ValueError(
'Invalid value for parameter `field`: Should be a field name or a Field instance ')

if usedisplay and hasattr(obj, 'get_%s_display' % fieldname):
value = getattr(obj, 'get_%s_display' % fieldname)()
Expand Down Expand Up @@ -149,7 +152,8 @@ def get_field_by_path(model, field_path):
parts = field_path.split('.')
target = parts[0]
if target in model._meta.get_all_field_names():
field_object, model, direct, m2m = model._meta.get_field_by_name(target)
field_object, model, direct, m2m = model._meta.get_field_by_name(
target)
if isinstance(field_object, models.fields.related.ForeignKey):
if parts[1:]:
return get_field_by_path(field_object.rel.to, '.'.join(parts[1:]))
Expand Down Expand Up @@ -215,7 +219,8 @@ def get_verbose_name(model_or_queryset, field):
elif isinstance(field, models.Field):
field = field
else:
raise ValueError('`get_verbose_name` field_path must be string or Field class')
raise ValueError(
'`get_verbose_name` field_path must be string or Field class')

return field.verbose_name

Expand Down Expand Up @@ -252,3 +257,16 @@ def flatten(iterable):
def model_supports_transactions(instance):
alias = router.db_for_write(instance)
return connections[alias].features.supports_transactions


def get_filename_from_qs(queryset, extension=""):
base = queryset.model._meta.verbose_name_plural.lower().encode('us-ascii', 'replace')

return six.b("%s.%s" % (base.replace(" ", "_"), extension))


def get_response(content_type='text/plain', filename='', content='',
response_class=HttpResponse):
response = response_class(content, content_type=content_type)
response['Content-Disposition'] = six.b('attachment;filename="%s"' % filename)
return response

0 comments on commit 620b870

Please sign in to comment.