Loading django/db/models/__init__.py +0 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,6 @@ from django.db.models.expressions import ( # NOQA from django.db.models.fields import * # NOQA from django.db.models.fields.files import FileField, ImageField # NOQA from django.db.models.fields.proxy import OrderWrt # NOQA from django.db.models.fields.subclassing import SubfieldBase # NOQA from django.db.models.lookups import Lookup, Transform # NOQA from django.db.models.manager import Manager # NOQA from django.db.models.query import Q, Prefetch, QuerySet # NOQA Loading django/db/models/fields/subclassing.pydeleted 100644 → 0 +0 −63 Original line number Diff line number Diff line """ Convenience routines for creating non-trivial Field subclasses, as well as backwards compatibility utilities. Add SubfieldBase as the metaclass for your Field subclass, implement to_python() and the other necessary methods and everything will work seamlessly. """ import warnings from django.utils.deprecation import RemovedInDjango110Warning class SubfieldBase(type): """ A metaclass for custom Field subclasses. This ensures the model's attribute has the descriptor protocol attached to it. """ def __new__(cls, name, bases, attrs): warnings.warn("SubfieldBase has been deprecated. Use Field.from_db_value instead.", RemovedInDjango110Warning) new_class = super(SubfieldBase, cls).__new__(cls, name, bases, attrs) new_class.contribute_to_class = make_contrib( new_class, attrs.get('contribute_to_class') ) return new_class class Creator(object): """ A placeholder class that provides a way to set the attribute on the model. """ def __init__(self, field): self.field = field def __get__(self, obj, type=None): if obj is None: return self return obj.__dict__[self.field.name] def __set__(self, obj, value): obj.__dict__[self.field.name] = self.field.to_python(value) def make_contrib(superclass, func=None): """ Returns a suitable contribute_to_class() method for the Field subclass. If 'func' is passed in, it is the existing contribute_to_class() method on the subclass and it is called before anything else. It is assumed in this case that the existing contribute_to_class() calls all the necessary superclass methods. """ def contribute_to_class(self, cls, name, **kwargs): if func: func(self, cls, name, **kwargs) else: super(superclass, self).contribute_to_class(cls, name, **kwargs) setattr(cls, self.name, Creator(self)) return contribute_to_class docs/howto/custom-model-fields.txt +0 −7 Original line number Diff line number Diff line Loading @@ -428,13 +428,6 @@ get out of the way. Converting values to Python objects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionchanged:: 1.8 Historically, Django provided a metaclass called ``SubfieldBase`` which always called :meth:`~Field.to_python` on assignment. This did not play nicely with custom database transformations, aggregation, or values queries, so it has been replaced with :meth:`~Field.from_db_value`. If your custom :class:`~Field` class deals with data structures that are more complex than strings, dates, integers, or floats, then you may need to override :meth:`~Field.from_db_value` and :meth:`~Field.to_python`. Loading tests/field_subclassing/fields.py +0 −88 Original line number Diff line number Diff line from __future__ import unicode_literals import json import warnings from django.db import models from django.utils import six from django.utils.deconstruct import deconstructible from django.utils.deprecation import RemovedInDjango110Warning from django.utils.encoding import force_text, python_2_unicode_compatible # Catch warning about subfieldbase -- remove in Django 1.10 warnings.filterwarnings( 'ignore', 'SubfieldBase has been deprecated. Use Field.from_db_value instead.', RemovedInDjango110Warning ) @deconstructible @python_2_unicode_compatible class Small(object): """ A simple class to show that non-trivial Python objects can be used as attributes. """ def __init__(self, first, second): self.first, self.second = first, second def __str__(self): return '%s%s' % (force_text(self.first), force_text(self.second)) def __eq__(self, other): if isinstance(other, self.__class__): return self.first == other.first and self.second == other.second return False class SmallField(six.with_metaclass(models.SubfieldBase, models.Field)): """ Turns the "Small" class into a Django field. Because of the similarities with normal character fields and the fact that Small.__unicode__ does something sensible, we don't need to implement a lot here. """ def __init__(self, *args, **kwargs): kwargs['max_length'] = 2 super(SmallField, self).__init__(*args, **kwargs) def get_internal_type(self): return 'CharField' def to_python(self, value): if isinstance(value, Small): return value return Small(value[0], value[1]) def get_db_prep_save(self, value, connection): return six.text_type(value) def get_prep_lookup(self, lookup_type, value): if lookup_type == 'exact': return force_text(value) if lookup_type == 'in': return [force_text(v) for v in value] if lookup_type == 'isnull': return [] raise TypeError('Invalid lookup type: %r' % lookup_type) class SmallerField(SmallField): pass class JSONField(six.with_metaclass(models.SubfieldBase, models.TextField)): description = ("JSONField automatically serializes and deserializes values to " "and from JSON.") def to_python(self, value): if not value: return None if isinstance(value, six.string_types): value = json.loads(value) return value def get_db_prep_save(self, value, connection): if value is None: return None return json.dumps(value) class CustomTypedField(models.TextField): Loading tests/field_subclassing/models.pydeleted 100644 → 0 +0 −34 Original line number Diff line number Diff line """ Tests for field subclassing. """ from django.db import models from django.utils.encoding import force_text, python_2_unicode_compatible from .fields import JSONField, Small, SmallerField, SmallField @python_2_unicode_compatible class MyModel(models.Model): name = models.CharField(max_length=10) data = SmallField('small field') def __str__(self): return force_text(self.name) class OtherModel(models.Model): data = SmallerField() class ChoicesModel(models.Model): SMALL_AB = Small('a', 'b') SMALL_CD = Small('c', 'd') SMALL_CHOICES = ( (SMALL_AB, str(SMALL_AB)), (SMALL_CD, str(SMALL_CD)), ) data = SmallField('small field', choices=SMALL_CHOICES) class DataModel(models.Model): data = JSONField() Loading
django/db/models/__init__.py +0 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,6 @@ from django.db.models.expressions import ( # NOQA from django.db.models.fields import * # NOQA from django.db.models.fields.files import FileField, ImageField # NOQA from django.db.models.fields.proxy import OrderWrt # NOQA from django.db.models.fields.subclassing import SubfieldBase # NOQA from django.db.models.lookups import Lookup, Transform # NOQA from django.db.models.manager import Manager # NOQA from django.db.models.query import Q, Prefetch, QuerySet # NOQA Loading
django/db/models/fields/subclassing.pydeleted 100644 → 0 +0 −63 Original line number Diff line number Diff line """ Convenience routines for creating non-trivial Field subclasses, as well as backwards compatibility utilities. Add SubfieldBase as the metaclass for your Field subclass, implement to_python() and the other necessary methods and everything will work seamlessly. """ import warnings from django.utils.deprecation import RemovedInDjango110Warning class SubfieldBase(type): """ A metaclass for custom Field subclasses. This ensures the model's attribute has the descriptor protocol attached to it. """ def __new__(cls, name, bases, attrs): warnings.warn("SubfieldBase has been deprecated. Use Field.from_db_value instead.", RemovedInDjango110Warning) new_class = super(SubfieldBase, cls).__new__(cls, name, bases, attrs) new_class.contribute_to_class = make_contrib( new_class, attrs.get('contribute_to_class') ) return new_class class Creator(object): """ A placeholder class that provides a way to set the attribute on the model. """ def __init__(self, field): self.field = field def __get__(self, obj, type=None): if obj is None: return self return obj.__dict__[self.field.name] def __set__(self, obj, value): obj.__dict__[self.field.name] = self.field.to_python(value) def make_contrib(superclass, func=None): """ Returns a suitable contribute_to_class() method for the Field subclass. If 'func' is passed in, it is the existing contribute_to_class() method on the subclass and it is called before anything else. It is assumed in this case that the existing contribute_to_class() calls all the necessary superclass methods. """ def contribute_to_class(self, cls, name, **kwargs): if func: func(self, cls, name, **kwargs) else: super(superclass, self).contribute_to_class(cls, name, **kwargs) setattr(cls, self.name, Creator(self)) return contribute_to_class
docs/howto/custom-model-fields.txt +0 −7 Original line number Diff line number Diff line Loading @@ -428,13 +428,6 @@ get out of the way. Converting values to Python objects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionchanged:: 1.8 Historically, Django provided a metaclass called ``SubfieldBase`` which always called :meth:`~Field.to_python` on assignment. This did not play nicely with custom database transformations, aggregation, or values queries, so it has been replaced with :meth:`~Field.from_db_value`. If your custom :class:`~Field` class deals with data structures that are more complex than strings, dates, integers, or floats, then you may need to override :meth:`~Field.from_db_value` and :meth:`~Field.to_python`. Loading
tests/field_subclassing/fields.py +0 −88 Original line number Diff line number Diff line from __future__ import unicode_literals import json import warnings from django.db import models from django.utils import six from django.utils.deconstruct import deconstructible from django.utils.deprecation import RemovedInDjango110Warning from django.utils.encoding import force_text, python_2_unicode_compatible # Catch warning about subfieldbase -- remove in Django 1.10 warnings.filterwarnings( 'ignore', 'SubfieldBase has been deprecated. Use Field.from_db_value instead.', RemovedInDjango110Warning ) @deconstructible @python_2_unicode_compatible class Small(object): """ A simple class to show that non-trivial Python objects can be used as attributes. """ def __init__(self, first, second): self.first, self.second = first, second def __str__(self): return '%s%s' % (force_text(self.first), force_text(self.second)) def __eq__(self, other): if isinstance(other, self.__class__): return self.first == other.first and self.second == other.second return False class SmallField(six.with_metaclass(models.SubfieldBase, models.Field)): """ Turns the "Small" class into a Django field. Because of the similarities with normal character fields and the fact that Small.__unicode__ does something sensible, we don't need to implement a lot here. """ def __init__(self, *args, **kwargs): kwargs['max_length'] = 2 super(SmallField, self).__init__(*args, **kwargs) def get_internal_type(self): return 'CharField' def to_python(self, value): if isinstance(value, Small): return value return Small(value[0], value[1]) def get_db_prep_save(self, value, connection): return six.text_type(value) def get_prep_lookup(self, lookup_type, value): if lookup_type == 'exact': return force_text(value) if lookup_type == 'in': return [force_text(v) for v in value] if lookup_type == 'isnull': return [] raise TypeError('Invalid lookup type: %r' % lookup_type) class SmallerField(SmallField): pass class JSONField(six.with_metaclass(models.SubfieldBase, models.TextField)): description = ("JSONField automatically serializes and deserializes values to " "and from JSON.") def to_python(self, value): if not value: return None if isinstance(value, six.string_types): value = json.loads(value) return value def get_db_prep_save(self, value, connection): if value is None: return None return json.dumps(value) class CustomTypedField(models.TextField): Loading
tests/field_subclassing/models.pydeleted 100644 → 0 +0 −34 Original line number Diff line number Diff line """ Tests for field subclassing. """ from django.db import models from django.utils.encoding import force_text, python_2_unicode_compatible from .fields import JSONField, Small, SmallerField, SmallField @python_2_unicode_compatible class MyModel(models.Model): name = models.CharField(max_length=10) data = SmallField('small field') def __str__(self): return force_text(self.name) class OtherModel(models.Model): data = SmallerField() class ChoicesModel(models.Model): SMALL_AB = Small('a', 'b') SMALL_CD = Small('c', 'd') SMALL_CHOICES = ( (SMALL_AB, str(SMALL_AB)), (SMALL_CD, str(SMALL_CD)), ) data = SmallField('small field', choices=SMALL_CHOICES) class DataModel(models.Model): data = JSONField()