From 1b9d617bde45934e9d15ee57f79c821750e2ebac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADn?= Date: Wed, 11 Sep 2013 10:49:03 +0200 Subject: [PATCH] Support to python 3, improvements in the readme and fix a little detail --- CHANGES.rst | 10 +- COPYING.LGPLv3 | 165 +++++++++++++++++++++++++++ MANIFEST.in | 1 + README.rst | 10 +- setup.py | 21 +++- src/multiselectfield/db/fields.py | 48 +++++++- src/multiselectfield/forms/fields.py | 19 ++- 7 files changed, 265 insertions(+), 9 deletions(-) create mode 100644 COPYING.LGPLv3 diff --git a/CHANGES.rst b/CHANGES.rst index ab1ec37..2aa238a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,15 @@ +0.0.3 (2013-09-11) +------------------ + +* Python 3 compatible +* Fix an error, the snippet had another error when the choices were translatables +* Improvements in the README file + + 0.0.2 (2012-09-28) ------------------ -* Fix a error, the snippet had a error. +* Fix an error, the snippet had an error. 0.0.1 (2012-09-27) ------------------ diff --git a/COPYING.LGPLv3 b/COPYING.LGPLv3 new file mode 100644 index 0000000..3fe2a4b --- /dev/null +++ b/COPYING.LGPLv3 @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in index 0fa2e19..78c6216 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,4 @@ include README.rst include CHANGES.rst +include COPYING.LGPLv3 include *.py diff --git a/README.rst b/README.rst index dad65df..9ba1090 100644 --- a/README.rst +++ b/README.rst @@ -35,17 +35,23 @@ In your models.py ... + MY_CHOICES = (('item_key1', 'Item title1'), + ('item_key2', 'Item title2'), + ('item_key3', 'Item title3'), + ('item_key4', 'Item title4'), + ('item_key5', 'Item title5')) + class MyModel(models.Model): ..... - my_field = MultiSelectField(verbose_name=_('xxx'), choices=MY_CHOICES) + my_field = MultiSelectField(choices=MY_CHOICES, max_length=20) Development =========== You can get the last bleeding edge version of django-configfield by doing a clone -of its hg repository:: +of its git repository:: git clone https://github.com/goinnn/django-multiselectfield diff --git a/setup.py b/setup.py index 26ee311..f374070 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,20 @@ -#http://djangosnippets.org/users/danielroseman/ # -*- coding: utf-8 -*- +# Copyright (c) 2012-2013 by Pablo Martín +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this programe. If not, see . + +# Initial code got from http://djangosnippets.org/users/danielroseman/ import os from setuptools import setup, find_packages @@ -11,7 +26,7 @@ def read(*rnames): setup( name="django-multiselectfield", version="0.0.2", - author="Daniel Roseman", + author="Daniel Roseman and Pablo Martin", author_email="goinnn@gmail.com", description="Django multiple select field", long_description=(read('README.rst') + '\n\n' + read('CHANGES.rst')), @@ -19,6 +34,8 @@ setup( 'Development Status :: 4 - Beta', 'Framework :: Django', 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', ], license="LGPL 3", keywords="django,multiple,select,field,choices", diff --git a/src/multiselectfield/db/fields.py b/src/multiselectfield/db/fields.py index ee4a8ae..3188296 100644 --- a/src/multiselectfield/db/fields.py +++ b/src/multiselectfield/db/fields.py @@ -1,13 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2012-2013 by Pablo Martín +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this programe. If not, see . + + +import sys + from django.db import models from django.utils.text import capfirst from django.core import exceptions from ..forms.fields import MultiSelectFormField +if sys.version_info.major == 2: + string = basestring + string_type = unicode +else: + string = str + string_type = string + +# Code from six egg https://bitbucket.org/gutworth/six/src/a3641cb211cc360848f1e2dd92e9ae6cd1de55dd/six.py?at=default + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + for slots_var in orig_vars.get('__slots__', ()): + orig_vars.pop(slots_var) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + class MultiSelectField(models.Field): """ Choice values can not contain commas. """ - __metaclass__ = models.SubfieldBase def get_internal_type(self): return "CharField" @@ -47,7 +86,7 @@ class MultiSelectField(models.Field): return MultiSelectFormField(**defaults) def get_prep_value(self, value): - if isinstance(value, basestring): + if isinstance(value, string): return value elif isinstance(value, list): return ",".join(value) @@ -60,9 +99,12 @@ class MultiSelectField(models.Field): def contribute_to_class(self, cls, name): super(MultiSelectField, self).contribute_to_class(cls, name) if self.choices: - func = lambda self, fieldname = name, choicedict = dict(self.choices): ",".join([choicedict.get(value, value) for value in getattr(self, fieldname)]) + func = lambda self, fieldname = name, choicedict = dict(self.choices): ",".join([string_type(choicedict.get(value, value)) for value in getattr(self, fieldname)]) setattr(cls, 'get_%s_display' % self.name, func) + +MultiSelectField = add_metaclass(models.SubfieldBase)(MultiSelectField) + try: from south.modelsinspector import add_introspection_rules add_introspection_rules([], ['^multiselectfield\.db.fields\.MultiSelectField']) diff --git a/src/multiselectfield/forms/fields.py b/src/multiselectfield/forms/fields.py index d1f369d..23e4491 100644 --- a/src/multiselectfield/forms/fields.py +++ b/src/multiselectfield/forms/fields.py @@ -1,3 +1,19 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2012-2013 by Pablo Martín +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this programe. If not, see . + from django import forms from django.contrib.humanize.templatetags.humanize import apnumber from django.template.defaultfilters import pluralize @@ -15,5 +31,6 @@ class MultiSelectFormField(forms.MultipleChoiceField): raise forms.ValidationError(self.error_messages['required']) if value and self.max_choices and len(value) > self.max_choices: raise forms.ValidationError('You must select a maximum of %s choice%s.' - % (apnumber(self.max_choices), pluralize(self.max_choices))) + % (apnumber(self.max_choices), + pluralize(self.max_choices))) return value