mirror of
https://github.com/django/django.git
synced 2025-06-06 12:09:11 +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:
parent
a6a6c4117b
commit
f64c581497
@ -104,6 +104,17 @@ class SingleRelatedObjectDescriptor(object):
|
|||||||
setattr(instance, cache_name, rel_obj)
|
setattr(instance, cache_name, rel_obj)
|
||||||
return 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):
|
class ForeignRelatedObjectsDescriptor(object):
|
||||||
# This class provides the functionality that makes the related-object
|
# This class provides the functionality that makes the related-object
|
||||||
# managers available as attributes on a model class, for fields that have
|
# managers available as attributes on a model class, for fields that have
|
||||||
@ -130,8 +141,7 @@ class ForeignRelatedObjectsDescriptor(object):
|
|||||||
|
|
||||||
def add(self, *objs):
|
def add(self, *objs):
|
||||||
for obj in objs:
|
for obj in objs:
|
||||||
val = getattr(instance, rel_field.rel.get_related_field().attname)
|
setattr(obj, rel_field.name, instance)
|
||||||
setattr(obj, rel_field.attname, val)
|
|
||||||
obj.save()
|
obj.save()
|
||||||
add.alters_data = True
|
add.alters_data = True
|
||||||
|
|
||||||
@ -146,8 +156,9 @@ class ForeignRelatedObjectsDescriptor(object):
|
|||||||
def remove(self, *objs):
|
def remove(self, *objs):
|
||||||
val = getattr(instance, rel_field.rel.get_related_field().attname)
|
val = getattr(instance, rel_field.rel.get_related_field().attname)
|
||||||
for obj in objs:
|
for obj in objs:
|
||||||
|
# Is obj actually part of this descriptor set?
|
||||||
if getattr(obj, rel_field.attname) == val:
|
if getattr(obj, rel_field.attname) == val:
|
||||||
setattr(obj, rel_field.attname, None)
|
setattr(obj, rel_field.name, None)
|
||||||
obj.save()
|
obj.save()
|
||||||
else:
|
else:
|
||||||
raise rel_field.rel.to.DoesNotExist, "'%s' is not related to '%s'." % (obj, instance)
|
raise rel_field.rel.to.DoesNotExist, "'%s' is not related to '%s'." % (obj, instance)
|
||||||
@ -155,7 +166,7 @@ class ForeignRelatedObjectsDescriptor(object):
|
|||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
for obj in self.all():
|
for obj in self.all():
|
||||||
setattr(obj, rel_field.attname, None)
|
setattr(obj, rel_field.name, None)
|
||||||
obj.save()
|
obj.save()
|
||||||
add.alters_data = True
|
add.alters_data = True
|
||||||
|
|
||||||
|
@ -71,6 +71,22 @@ John's second story
|
|||||||
>>> r2.article_set.all()
|
>>> r2.article_set.all()
|
||||||
[Paul's story]
|
[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
|
# Reporter cannot be null - there should not be a clear or remove method
|
||||||
>>> hasattr(r2.article_set, 'remove')
|
>>> hasattr(r2.article_set, 'remove')
|
||||||
False
|
False
|
||||||
|
Loading…
x
Reference in New Issue
Block a user