From a85902b8031b695401ceb4de8d996c3e90bf8bea Mon Sep 17 00:00:00 2001 From: laiyonghao Date: Sat, 24 Oct 2015 18:04:10 +0800 Subject: [PATCH] ported to py3.4 --- README.rst | 29 +++++++++----- django_qbe/exports.py | 8 +++- django_qbe/forms.py | 8 ++-- django_qbe/operators.py | 5 ++- .../management/commands/qbe_export.py | 2 +- django_qbe/savedqueries/models.py | 3 +- django_qbe/templatetags/qbe_tags.py | 5 ++- django_qbe/urls.py | 2 +- django_qbe/utils.py | 38 +++++++++++-------- django_qbe/widgets.py | 5 ++- setup.py | 2 +- 11 files changed, 68 insertions(+), 39 deletions(-) diff --git a/README.rst b/README.rst index bf269a3..a5fb7a2 100644 --- a/README.rst +++ b/README.rst @@ -36,23 +36,32 @@ Adding to the project settings:: # [...] Any other application ) -And adding the urlconf in your project urls.py:: - - # qbe - url(r'^qbe/', include('django_qbe.urls')), - Add the context processor ``django.core.context_processors.static``:: - TEMPLATE_CONTEXT_PROCESSORS = ( - # [...] django context processors - 'django.core.context_processors.static', - # [...] Any other context processors - ) +TEMPLATES = [ +{ + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + # [...] django context processors + 'django.template.context_processors.static', + # [...] Any other context processors + ], + }, +}, +] See the `Django documentation on static files`__ for details. __ staticfiles_ +And adding the urlconf in your project urls.py:: + + # qbe + url(r'^qbe/', include('django_qbe.urls')), + That's all. Then you can access to http://host:port/qbe However, you can add a link from your admin page changing the admin index template fo your AdminSite:: diff --git a/django_qbe/exports.py b/django_qbe/exports.py index a25d188..0eda603 100644 --- a/django_qbe/exports.py +++ b/django_qbe/exports.py @@ -1,7 +1,11 @@ +from future import standard_library +standard_library.install_aliases() +from builtins import str +from builtins import object # -*- coding: utf-8 -*- import codecs import csv -from StringIO import StringIO +from io import StringIO from django.http import HttpResponse from django.utils.datastructures import SortedDict @@ -45,7 +49,7 @@ def __init__(self, f, dialect=csv.excel_tab, encoding="utf-8", **kwds): self.encoder = codecs.getincrementalencoder(encoding)() def writerow(self, row): - self.writer.writerow([unicode(s).encode("utf-8") for s in row]) + self.writer.writerow([str(s).encode("utf-8") for s in row]) # Fetch UTF-8 output from the queue ... data = self.queue.getvalue() data = data.decode("utf-8") diff --git a/django_qbe/forms.py b/django_qbe/forms.py index ce57150..1b39bc2 100644 --- a/django_qbe/forms.py +++ b/django_qbe/forms.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +from __future__ import print_function +from builtins import range import collections from django import forms from django.db import connections @@ -133,7 +135,7 @@ def clean(self): params) = self.get_query_parts() if not selects: validation_message = _(u"At least you must check a row to get.") - raise forms.ValidationError, validation_message + raise forms.ValidationError(validation_message) self._selects = selects self._aliases = aliases self._froms = froms @@ -225,7 +227,7 @@ def get_query_parts(self): wheres.append(u"%s %s" % (lookup_cast(operator) % db_field, db_operator)) - elif operator in self._custom_operators.keys(): + elif operator in list(self._custom_operators.keys()): CustOperator = self._custom_operators[operator] custom_operator = CustOperator(db_field, operator, over) @@ -307,7 +309,7 @@ def get_results(self, limit=None, offset=None, query=None, admin_name=None, else: sql = query if settings.DEBUG: - print sql + print(sql) cursor = self._db_connection.cursor() cursor.execute(sql, tuple(self._params)) query_results = cursor.fetchall() diff --git a/django_qbe/operators.py b/django_qbe/operators.py index 81eb656..ac6ffa0 100644 --- a/django_qbe/operators.py +++ b/django_qbe/operators.py @@ -1,7 +1,9 @@ +from builtins import object from django.conf import settings from django.db import connections from django.db.models.fields import Field from django.utils.importlib import import_module +from future.utils import with_metaclass DATABASES = settings.DATABASES @@ -39,7 +41,7 @@ def get_operators(self): return self.operators -class CustomOperator: +class CustomOperator(with_metaclass(OperatorMount, object)): """ Mount point for operators which refer to actions that can be performed. @@ -52,7 +54,6 @@ class CustomOperator: label The label that will be displayed in the criteria dropdown ======== ======================================================== """ - __metaclass__ = OperatorMount def __init__(self, db_field, operator, value, db_alias="default"): self.params = [] diff --git a/django_qbe/savedqueries/management/commands/qbe_export.py b/django_qbe/savedqueries/management/commands/qbe_export.py index c3724d3..917bbd7 100644 --- a/django_qbe/savedqueries/management/commands/qbe_export.py +++ b/django_qbe/savedqueries/management/commands/qbe_export.py @@ -11,7 +11,7 @@ class Command(BaseCommand): - available_formats = ", ".join(formats.keys()) + available_formats = ", ".join(list(formats.keys())) option_list = BaseCommand.option_list + ( make_option('--output', dest='output', diff --git a/django_qbe/savedqueries/models.py b/django_qbe/savedqueries/models.py index 6d45103..f0a5701 100644 --- a/django_qbe/savedqueries/models.py +++ b/django_qbe/savedqueries/models.py @@ -1,3 +1,4 @@ +from builtins import object import pickle from django.db import models from django.utils.translation import ugettext_lazy as _ @@ -21,7 +22,7 @@ class SavedQuery(models.Model): editable=False) date_updated = models.DateTimeField(_("date updated"), editable=False) - class Meta: + class Meta(object): verbose_name = _("Saved query") verbose_name_plural = _("Saved queries") diff --git a/django_qbe/templatetags/qbe_tags.py b/django_qbe/templatetags/qbe_tags.py index 1f1adad..1c62cf7 100644 --- a/django_qbe/templatetags/qbe_tags.py +++ b/django_qbe/templatetags/qbe_tags.py @@ -1,4 +1,7 @@ # -*- coding: utf-8 -*- +from __future__ import division +from builtins import range +from past.utils import old_div from django import template from django.utils.safestring import mark_safe @@ -29,7 +32,7 @@ def _get_range_markup(range_from, range_to): if total_pages < rows_per_page or not rows_per_page: pages = 1 else: - pages = (total_pages / rows_per_page) + pages = (old_div(total_pages, rows_per_page)) if total_pages % rows_per_page != 0: pages += 1 output = [] diff --git a/django_qbe/urls.py b/django_qbe/urls.py index 5bf6052..4eb7f94 100644 --- a/django_qbe/urls.py +++ b/django_qbe/urls.py @@ -12,7 +12,7 @@ url(r'^bookmark/$', 'qbe_bookmark', name="qbe_bookmark"), url(r'^proxy/$', 'qbe_proxy', name="qbe_proxy"), url(r'^auto/$', 'qbe_autocomplete', name="qbe_autocomplete"), - url(r'^(?P(.*))/results\.(?P(%s))$' % "|".join(formats.keys()), 'qbe_export', name="qbe_export"), + url(r'^(?P(.*))/results\.(?P(%s))$' % "|".join(list(formats.keys())), 'qbe_export', name="qbe_export"), url(r'^(?P(.*))/results/$', 'qbe_results', name="qbe_results"), url(r'^(?P(.*))/$', 'qbe_form', name="qbe_form"), ) diff --git a/django_qbe/utils.py b/django_qbe/utils.py index 1fbd105..c70bf0d 100644 --- a/django_qbe/utils.py +++ b/django_qbe/utils.py @@ -1,4 +1,11 @@ # -*- coding: utf-8 -*- +from __future__ import print_function +from __future__ import division +from past.builtins import cmp +from builtins import zip +from builtins import filter +from builtins import range +from past.utils import old_div import base64 import pickle import random @@ -6,6 +13,7 @@ from copy import copy from hashlib import md5 from json import dumps +from functools import reduce try: from itertools import combinations except ImportError: @@ -14,7 +22,7 @@ def combinations(items, n): if n == 0: yield [] else: - for i in xrange(len(items)): + for i in range(len(items)): for cc in combinations(items[i + 1:], n - 1): yield [items[i]] + cc @@ -66,7 +74,7 @@ def qbe_models(admin_site=None, only_admin_models=False, json=False): app_models_with_no_includes = get_models(include_auto_created=False, include_deferred=False) if admin_site: - admin_models = [m for m, a in admin_site._registry.items()] + admin_models = [m for m, a in list(admin_site._registry.items())] else: admin_models = [] if only_admin_models: @@ -191,8 +199,8 @@ def add_relation(model, field, extras=""): def qbe_graph(admin_site=None, directed=False): models = qbe_models(admin_site) graph = {} - for k, v in models.items(): - for l, w in v.items(): + for k, v in list(models.items()): + for l, w in list(v.items()): key = "%s.%s" % (k, l) if key not in graph: graph[key] = [] @@ -266,11 +274,11 @@ def qbe_tree(graph, nodes, root=None): def remove_leafs(tree, nodes): def get_leafs(tree, nodes): - return [node for node, edges in tree.items() + return [node for node, edges in list(tree.items()) if len(edges) < 2 and node not in nodes] def delete_edge_leafs(tree, leaf): - for node, edges in tree.items(): + for node, edges in list(tree.items()): for node_edge, neighbor, neighbor_edge in edges: if leaf == neighbor: edge = (node_edge, neighbor, neighbor_edge) @@ -290,7 +298,7 @@ def delete_edge_leafs(tree, leaf): def qbe_forest(graph, nodes): forest = [] - for node, edges in graph.items(): + for node, edges in list(graph.items()): tree, are_all = qbe_tree(graph, copy(nodes), root=node) if are_all and tree not in forest: forest.append(tree) @@ -365,7 +373,7 @@ def _combine(items, val=None, paths=None, length=None): def visited_path(x): return x not in paths - path = filter(visited_path, path) + path = list(filter(visited_path, path)) paths.extend(path) return paths @@ -383,7 +391,7 @@ def combine(items, k=None): if k is not None: k = k % length # Python division by default is integer division (~ floor(a/b)) - indices = [(k % (lengths[i] * repeats[i])) / repeats[i] + indices = [old_div((k % (lengths[i] * repeats[i])), repeats[i]) for i in range(length_items)] return [items[i][indices[i]] for i in range(length_items)] else: @@ -392,14 +400,14 @@ def combine(items, k=None): row = [] for subset in item: row.extend([subset] * repeats[i]) - times = length / len(row) + times = old_div(length, len(row)) matrix.append(row * times) # Transpose the matrix or return the columns instead rows - return zip(*matrix) + return list(zip(*matrix)) def graphs_join(graphs): - print "Combine % elements" % len(graphs) + print("Combine % elements" % len(graphs)) return [] @@ -423,7 +431,7 @@ def autocomplete_graph(admin_site, current_models, directed=False): def pickle_encode(session_dict): "Returns the given session dictionary pickled and encoded as a string." pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL) - return base64.encodestring(pickled + get_query_hash(pickled)) + return base64.encodestring(pickled + get_query_hash(pickled).encode()) # Adapted from django.contrib.sessions.backends.base @@ -431,7 +439,7 @@ def pickle_decode(session_data): # The '+' character is translated to ' ' in request session_data = session_data.replace(" ", "+") # The length of the encoded string should be a multiple of 4 - while (((len(session_data) / 4.0) - (len(session_data) / 4)) != 0): + while (((old_div(len(session_data), 4.0)) - (old_div(len(session_data), 4))) != 0): session_data += u"=" encoded_data = base64.decodestring(session_data) pickled, tamper_check = encoded_data[:-32], encoded_data[-32:] @@ -447,4 +455,4 @@ def pickle_decode(session_data): def get_query_hash(data): - return md5(data + settings.SECRET_KEY).hexdigest() + return md5(data + str.encode(settings.SECRET_KEY)).hexdigest() diff --git a/django_qbe/widgets.py b/django_qbe/widgets.py index 5040be2..88309ba 100644 --- a/django_qbe/widgets.py +++ b/django_qbe/widgets.py @@ -1,3 +1,4 @@ +from builtins import object # -*- coding: utf-8 -*- from django.forms.util import flatatt from django.forms.widgets import MultiWidget, Select, TextInput, Widget @@ -51,7 +52,7 @@ def render(self, name, value=None, attrs=None, prelabel=None): class CriteriaInput(MultiWidget): - class Media: + class Media(object): js = ('django_qbe/js/qbe.widgets.js', ) def __init__(self, *args, **kwargs): @@ -62,7 +63,7 @@ def __init__(self, *args, **kwargs): # inject custom operators ALL_OPERATOR_CHOICES = OPERATOR_CHOICES - for operator_slug, operator in custom_operators.items(): + for operator_slug, operator in list(custom_operators.items()): ALL_OPERATOR_CHOICES += ((operator_slug, operator.label),) widgets = [Select(choices=ALL_OPERATOR_CHOICES), TextInput()] diff --git a/setup.py b/setup.py index 31ec780..6d83b97 100644 --- a/setup.py +++ b/setup.py @@ -40,5 +40,5 @@ def find_version(*parts): zip_safe=False, packages=find_packages(), include_package_data=True, - install_requires=['django-picklefield'], + install_requires=['future', 'six', 'django-picklefield'], )