mirror of
https://github.com/django/django.git
synced 2025-07-06 18:59:13 +00:00
queryset-refactor: Added a Model.from_sequence() constructor for internal and
advanced usage. git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7474 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
0b30bed861
commit
177f7d5164
@ -165,33 +165,6 @@ class ModelBase(type):
|
|||||||
class Model(object):
|
class Model(object):
|
||||||
__metaclass__ = ModelBase
|
__metaclass__ = ModelBase
|
||||||
|
|
||||||
def _get_pk_val(self, meta=None):
|
|
||||||
if not meta:
|
|
||||||
meta = self._meta
|
|
||||||
return getattr(self, meta.pk.attname)
|
|
||||||
|
|
||||||
def _set_pk_val(self, value):
|
|
||||||
return setattr(self, self._meta.pk.attname, value)
|
|
||||||
|
|
||||||
pk = property(_get_pk_val, _set_pk_val)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return smart_str(u'<%s: %s>' % (self.__class__.__name__, unicode(self)))
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
if hasattr(self, '__unicode__'):
|
|
||||||
return force_unicode(self).encode('utf-8')
|
|
||||||
return '%s object' % self.__class__.__name__
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val()
|
|
||||||
|
|
||||||
def __ne__(self, other):
|
|
||||||
return not self.__eq__(other)
|
|
||||||
|
|
||||||
def __hash__(self):
|
|
||||||
return hash(self._get_pk_val())
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
dispatcher.send(signal=signals.pre_init, sender=self.__class__, args=args, kwargs=kwargs)
|
dispatcher.send(signal=signals.pre_init, sender=self.__class__, args=args, kwargs=kwargs)
|
||||||
|
|
||||||
@ -264,6 +237,59 @@ class Model(object):
|
|||||||
raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
|
raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
|
||||||
dispatcher.send(signal=signals.post_init, sender=self.__class__, instance=self)
|
dispatcher.send(signal=signals.post_init, sender=self.__class__, instance=self)
|
||||||
|
|
||||||
|
def from_sequence(cls, values):
|
||||||
|
"""
|
||||||
|
An alternate class constructor, primarily for internal use.
|
||||||
|
|
||||||
|
Creates a model instance from a sequence of values (which corresponds
|
||||||
|
to all the non-many-to-many fields in creation order. If there are more
|
||||||
|
fields than values, the remaining (final) fields are given their
|
||||||
|
default values.
|
||||||
|
|
||||||
|
ForeignKey fields can only be initialised using id values, not
|
||||||
|
instances, in this method.
|
||||||
|
"""
|
||||||
|
dispatcher.send(signal=signals.pre_init, sender=cls, args=values,
|
||||||
|
kwargs={})
|
||||||
|
obj = Empty()
|
||||||
|
obj.__class__ = cls
|
||||||
|
field_iter = iter(obj._meta.fields)
|
||||||
|
for val, field in izip(values, field_iter):
|
||||||
|
setattr(obj, field.attname, val)
|
||||||
|
for field in field_iter:
|
||||||
|
setattr(obj, field.attname, field.get_default())
|
||||||
|
dispatcher.send(signal=signals.post_init, sender=cls, instance=obj)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
from_sequence = classmethod(from_sequence)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return smart_str(u'<%s: %s>' % (self.__class__.__name__, unicode(self)))
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if hasattr(self, '__unicode__'):
|
||||||
|
return force_unicode(self).encode('utf-8')
|
||||||
|
return '%s object' % self.__class__.__name__
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val()
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
return not self.__eq__(other)
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self._get_pk_val())
|
||||||
|
|
||||||
|
def _get_pk_val(self, meta=None):
|
||||||
|
if not meta:
|
||||||
|
meta = self._meta
|
||||||
|
return getattr(self, meta.pk.attname)
|
||||||
|
|
||||||
|
def _set_pk_val(self, value):
|
||||||
|
return setattr(self, self._meta.pk.attname, value)
|
||||||
|
|
||||||
|
pk = property(_get_pk_val, _set_pk_val)
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"""
|
"""
|
||||||
Save the current instance. Override this in a subclass if you want to
|
Save the current instance. Override this in a subclass if you want to
|
||||||
@ -533,6 +559,9 @@ def get_absolute_url(opts, func, self, *args, **kwargs):
|
|||||||
# MISC #
|
# MISC #
|
||||||
########
|
########
|
||||||
|
|
||||||
|
class Empty(object):
|
||||||
|
pass
|
||||||
|
|
||||||
if sys.version_info < (2, 5):
|
if sys.version_info < (2, 5):
|
||||||
# Prior to Python 2.5, Exception was an old-style class
|
# Prior to Python 2.5, Exception was an old-style class
|
||||||
def subclass_exception(name, parent, unused):
|
def subclass_exception(name, parent, unused):
|
||||||
|
@ -153,7 +153,7 @@ class QuerySet(object):
|
|||||||
obj, _ = get_cached_row(self.model, row, index_start,
|
obj, _ = get_cached_row(self.model, row, index_start,
|
||||||
max_depth, requested=requested)
|
max_depth, requested=requested)
|
||||||
else:
|
else:
|
||||||
obj = self.model(*row[index_start:])
|
obj = self.model.from_sequence(row[index_start:])
|
||||||
for i, k in enumerate(extra_select):
|
for i, k in enumerate(extra_select):
|
||||||
setattr(obj, k, row[i])
|
setattr(obj, k, row[i])
|
||||||
yield obj
|
yield obj
|
||||||
@ -646,7 +646,7 @@ def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0,
|
|||||||
|
|
||||||
restricted = requested is not None
|
restricted = requested is not None
|
||||||
index_end = index_start + len(klass._meta.fields)
|
index_end = index_start + len(klass._meta.fields)
|
||||||
obj = klass(*row[index_start:index_end])
|
obj = klass.from_sequence(row[index_start:index_end])
|
||||||
for f in klass._meta.fields:
|
for f in klass._meta.fields:
|
||||||
if (not f.rel or (not restricted and f.null) or
|
if (not f.rel or (not restricted and f.null) or
|
||||||
(restricted and f.name not in requested) or f.rel.parent_link):
|
(restricted and f.name not in requested) or f.rel.parent_link):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user