summaryrefslogtreecommitdiff
path: root/django/db/models/fields
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2007-11-18 05:48:24 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2007-11-18 05:48:24 +0000
commit3d07f94d68ae7ef69c336c36ee119ef49c1e6028 (patch)
tree5ddb605fbe53758ed57b876d73791691d8ebf7c6 /django/db/models/fields
parent44df4e390fc9e037a3ab2775ffd695c80831f0ee (diff)
queryset-refactor: Merged from trunk up to [6689].
git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6690 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/db/models/fields')
-rw-r--r--django/db/models/fields/__init__.py2
-rw-r--r--django/db/models/fields/subclassing.py53
2 files changed, 55 insertions, 0 deletions
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index e7c08d947e..af122b33d9 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -154,6 +154,8 @@ class Field(object):
# exactly which wacky database column type you want to use.
data_types = get_creation_module().DATA_TYPES
internal_type = self.get_internal_type()
+ if internal_type not in data_types:
+ return None
return data_types[internal_type] % self.__dict__
def validate_full(self, field_data, all_data):
diff --git a/django/db/models/fields/subclassing.py b/django/db/models/fields/subclassing.py
new file mode 100644
index 0000000000..1e4c8ca2e0
--- /dev/null
+++ b/django/db/models/fields/subclassing.py
@@ -0,0 +1,53 @@
+"""
+Convenience routines for creating non-trivial Field subclasses.
+
+Add SubfieldBase as the __metaclass__ for your Field subclass, implement
+to_python() and the other necessary methods and everything will work seamlessly.
+"""
+
+from django.utils.maxlength import LegacyMaxlength
+
+class SubfieldBase(LegacyMaxlength):
+ """
+ A metaclass for custom Field subclasses. This ensures the model's attribute
+ has the descriptor protocol attached to it.
+ """
+ def __new__(cls, base, name, attrs):
+ new_class = super(SubfieldBase, cls).__new__(cls, base, name, attrs)
+ new_class.contribute_to_class = make_contrib(
+ 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:
+ raise AttributeError('Can only be accessed via an instance.')
+ return self.value
+
+ def __set__(self, obj, value):
+ self.value = self.field.to_python(value)
+
+def make_contrib(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):
+ if func:
+ func(self, cls, name)
+ else:
+ super(self.__class__, self).contribute_to_class(cls, name)
+ setattr(cls, self.name, Creator(self))
+
+ return contribute_to_class
+