1
0
mirror of https://github.com/django/django.git synced 2025-04-14 20:34:36 +00:00

magic-removal: Fixed #1407 -- Added a __set__ method for the single object descriptor. This enables setting related objects using poll.choice = c, and ensures that the cache is kept accurate in the process.

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2435 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2006-02-28 11:36:20 +00:00
parent a6a6c4117b
commit f64c581497
2 changed files with 31 additions and 4 deletions

View File

@ -104,6 +104,17 @@ class SingleRelatedObjectDescriptor(object):
setattr(instance, cache_name, rel_obj)
return rel_obj
def __set__(self, instance, value):
# Set the value of the related field
if value:
val = getattr(value, self._field.rel.get_related_field().attname)
else:
val = None
setattr(instance, self._field.attname, val)
# Set the cache to point to the new object
setattr(instance, self._field.get_cache_name(), value)
class ForeignRelatedObjectsDescriptor(object):
# This class provides the functionality that makes the related-object
# managers available as attributes on a model class, for fields that have
@ -130,8 +141,7 @@ class ForeignRelatedObjectsDescriptor(object):
def add(self, *objs):
for obj in objs:
val = getattr(instance, rel_field.rel.get_related_field().attname)
setattr(obj, rel_field.attname, val)
setattr(obj, rel_field.name, instance)
obj.save()
add.alters_data = True
@ -146,8 +156,9 @@ class ForeignRelatedObjectsDescriptor(object):
def remove(self, *objs):
val = getattr(instance, rel_field.rel.get_related_field().attname)
for obj in objs:
# Is obj actually part of this descriptor set?
if getattr(obj, rel_field.attname) == val:
setattr(obj, rel_field.attname, None)
setattr(obj, rel_field.name, None)
obj.save()
else:
raise rel_field.rel.to.DoesNotExist, "'%s' is not related to '%s'." % (obj, instance)
@ -155,7 +166,7 @@ class ForeignRelatedObjectsDescriptor(object):
def clear(self):
for obj in self.all():
setattr(obj, rel_field.attname, None)
setattr(obj, rel_field.name, None)
obj.save()
add.alters_data = True

View File

@ -71,6 +71,22 @@ John's second story
>>> r2.article_set.all()
[Paul's story]
# Assign the article to the reporter directly using the descriptor
>>> new_article2.reporter = r
>>> new_article2.save()
>>> new_article2.reporter
John Smith
>>> new_article2.reporter.id
1
>>> r.article_set.all()
[This is a test, John's second story, Paul's story]
>>> r2.article_set.all()
[]
# Set the article back again.
>>> new_article2.reporter = r2
>>> new_article2.save()
# Reporter cannot be null - there should not be a clear or remove method
>>> hasattr(r2.article_set, 'remove')
False