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:
parent
a6a6c4117b
commit
f64c581497
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user