magic-removal: Refs #1407 -- Added remove() and clear() methods for ForeignKeys that allow nulls.

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2434 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2006-02-28 10:12:45 +00:00
parent f9ed0eded9
commit a6a6c4117b
3 changed files with 63 additions and 0 deletions

View File

@ -141,6 +141,24 @@ class ForeignRelatedObjectsDescriptor(object):
return new_obj
create.alters_data = True
# remove() and clear() are only provided if the ForeignKey can have a value of null.
if rel_field.null:
def remove(self, *objs):
val = getattr(instance, rel_field.rel.get_related_field().attname)
for obj in objs:
if getattr(obj, rel_field.attname) == val:
setattr(obj, rel_field.attname, None)
obj.save()
else:
raise rel_field.rel.to.DoesNotExist, "'%s' is not related to '%s'." % (obj, instance)
add.alters_data = True
def clear(self):
for obj in self.all():
setattr(obj, rel_field.attname, None)
obj.save()
add.alters_data = True
manager = RelatedManager()
manager.core_filters = {'%s__pk' % rel_field.name: getattr(instance, rel_field.rel.get_related_field().attname)}
manager.model = self.related.model

View File

@ -71,6 +71,12 @@ John's second story
>>> r2.article_set.all()
[Paul's story]
# Reporter cannot be null - there should not be a clear or remove method
>>> hasattr(r2.article_set, 'remove')
False
>>> hasattr(r2.article_set, 'clear')
False
# Reporter objects have access to their related Article objects.
>>> r.article_set.order_by('pub_date')
[This is a test, John's second story]

View File

@ -20,6 +20,9 @@ class Article(models.Model):
def __repr__(self):
return self.headline
class Meta:
ordering = ('headline',)
API_TESTS = """
# Create a Reporter.
>>> r = Reporter(name='John Smith')
@ -79,4 +82,40 @@ DoesNotExist
# To retrieve the articles with no reporters set, use "reporter__isnull=True".
>>> Article.objects.filter(reporter__isnull=True)
[Third]
# Set the reporter for the Third article
>>> r.article_set.add(a3)
>>> r.article_set.all()
[First, Second, Third]
# Remove an article from the set, and check that it was removed.
>>> r.article_set.remove(a3)
>>> r.article_set.all()
[First, Second]
>>> Article.objects.filter(reporter__isnull=True)
[Third]
# Create another article and reporter
>>> r2 = Reporter(name='Paul Jones')
>>> r2.save()
>>> a4 = r2.article_set.create(headline='Fourth')
>>> r2.article_set.all()
[Fourth]
# Try to remove a4 from a set it does not belong to
>>> r.article_set.remove(a4)
Traceback (most recent call last):
...
DoesNotExist: 'Fourth' is not related to 'John Smith'.
>>> r2.article_set.all()
[Fourth]
# Clear the rest of the set
>>> r.article_set.clear()
>>> r.article_set.all()
[]
>>> Article.objects.filter(reporter__isnull=True)
[First, Second, Third]
"""