Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

magic-removal: Refs #1407 -- Added remove() and clear() methods for F…

…oreignKeys that allow nulls.

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2434 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit a6a6c4117b6aa856abf099f357431e0d6684799e 1 parent f9ed0ed
@freakboy3742 freakboy3742 authored
View
18 django/db/models/fields/related.py
@@ -141,6 +141,24 @@ def create(self, **kwargs):
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
6 tests/modeltests/many_to_one/models.py
@@ -71,6 +71,12 @@ def __repr__(self):
>>> 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
39 tests/modeltests/many_to_one_null/models.py
@@ -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 @@ def __repr__(self):
# 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]
+
"""
Please sign in to comment.
Something went wrong with that request. Please try again.