diff options
| author | Alex Gaynor <alex.gaynor@gmail.com> | 2010-08-09 21:16:59 +0000 |
|---|---|---|
| committer | Alex Gaynor <alex.gaynor@gmail.com> | 2010-08-09 21:16:59 +0000 |
| commit | c7bd48cb9f645e5ff07d1e68b86130e3bb2b043f (patch) | |
| tree | a0459672ce695501236fa89879615a2896b42637 /django/db/models | |
| parent | 9b263c61f805947a06473fd5ca170e8b970aae32 (diff) | |
[soc2010/query-refactor] Improved the ListField implementation, and added an EmbeddedModelField.
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2010/query-refactor@13564 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/db/models')
| -rw-r--r-- | django/db/models/__init__.py | 2 | ||||
| -rw-r--r-- | django/db/models/fields/structures.py | 57 |
2 files changed, 57 insertions, 2 deletions
diff --git a/django/db/models/__init__.py b/django/db/models/__init__.py index 0736648a7b..6c0161a0e9 100644 --- a/django/db/models/__init__.py +++ b/django/db/models/__init__.py @@ -13,7 +13,7 @@ from django.db.models.fields.subclassing import SubfieldBase from django.db.models.fields.files import FileField, ImageField from django.db.models.fields.related import (ForeignKey, OneToOneField, ManyToManyField, ManyToOneRel, ManyToManyRel, OneToOneRel) -from django.db.models.fields.structures import ListField +from django.db.models.fields.structures import ListField, EmbeddedModel from django.db.models import signals # Admin stages. diff --git a/django/db/models/fields/structures.py b/django/db/models/fields/structures.py index 2d3822e932..b90164cc28 100644 --- a/django/db/models/fields/structures.py +++ b/django/db/models/fields/structures.py @@ -1,10 +1,15 @@ +from django.core.exceptions import ValidationError +from django.db.models.loading import cache from django.db.models.fields import Field +from django.db.models.fields.subclassing import SubfieldBase class ListField(Field): + __metaclass__ = SubfieldBase + def __init__(self, field_type): self.field_type = field_type - super(ListField, self).__init__() + super(ListField, self).__init__(default=[]) def get_prep_lookup(self, lookup_type, value): return self.field_type.get_prep_lookup(lookup_type, value) @@ -19,3 +24,53 @@ class ListField(Field): return self.field_type.get_db_prep_lookup( lookup_type, value, connection=connection, prepared=prepared ) + + def to_python(self, value): + try: + value = iter(value) + except TypeError: + raise ValidationError("Value should be iterable") + return [ + self.field_type.to_python(v) + for v in value + ] + + +class EmbeddedModel(Field): + __metaclass__ = SubfieldBase + + def __init__(self, to): + self.to = to + super(EmbeddedModel, self).__init__() + + def get_db_prep_save(self, value, connection): + data = {} + if not isinstance(value, self.to): + raise ValidationError("Value must be an instance of %s, got %s " + "instead" % (self.to, value)) + if type(value) is not self.to: + data["_cls"] = (value._meta.app_label, value._meta.object_name) + for field in value._meta.fields: + # If the field is a OneToOneField that makes the inheritance link, + # ignore it. + if field.rel and field.rel.parent_link: + continue + data[field.column] = field.get_db_prep_save( + getattr(value, field.name), connection=connection + ) + return data + + def to_python(self, value): + if isinstance(value, self.to): + return value + try: + value = dict(value) + except TypeError: + raise ValidationError("Value should be a dict") + + if "_cls" in value: + cls = cache.get_model(*value.pop("_cls")) + else: + cls = self.to + + return cls(**value) |
