Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Migrated m2m_through doctests. Thanks to the anonymous contributor.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14419 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit e0a1e474b6e0edc4c400af775002bbcde305fe41 1 parent 3d96540
@freakboy3742 freakboy3742 authored
View
272 tests/modeltests/m2m_through/models.py
@@ -63,275 +63,3 @@ class Friendship(models.Model):
first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set")
second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set")
date_friended = models.DateTimeField()
-
-__test__ = {'API_TESTS':"""
->>> from datetime import datetime
-
-### Creation and Saving Tests ###
-
->>> bob = Person.objects.create(name='Bob')
->>> jim = Person.objects.create(name='Jim')
->>> jane = Person.objects.create(name='Jane')
->>> rock = Group.objects.create(name='Rock')
->>> roll = Group.objects.create(name='Roll')
-
-# We start out by making sure that the Group 'rock' has no members.
->>> rock.members.all()
-[]
-
-# To make Jim a member of Group Rock, simply create a Membership object.
->>> m1 = Membership.objects.create(person=jim, group=rock)
-
-# We can do the same for Jane and Rock.
->>> m2 = Membership.objects.create(person=jane, group=rock)
-
-# Let's check to make sure that it worked. Jane and Jim should be members of Rock.
->>> rock.members.all()
-[<Person: Jane>, <Person: Jim>]
-
-# Now we can add a bunch more Membership objects to test with.
->>> m3 = Membership.objects.create(person=bob, group=roll)
->>> m4 = Membership.objects.create(person=jim, group=roll)
->>> m5 = Membership.objects.create(person=jane, group=roll)
-
-# We can get Jim's Group membership as with any ForeignKey.
->>> jim.group_set.all()
-[<Group: Rock>, <Group: Roll>]
-
-# Querying the intermediary model works like normal.
-# In this case we get Jane's membership to Rock.
->>> m = Membership.objects.get(person=jane, group=rock)
->>> m
-<Membership: Jane is a member of Rock>
-
-# Now we set some date_joined dates for further testing.
->>> m2.invite_reason = "She was just awesome."
->>> m2.date_joined = datetime(2006, 1, 1)
->>> m2.save()
-
->>> m5.date_joined = datetime(2004, 1, 1)
->>> m5.save()
-
->>> m3.date_joined = datetime(2004, 1, 1)
->>> m3.save()
-
-# It's not only get that works. Filter works like normal as well.
->>> Membership.objects.filter(person=jim)
-[<Membership: Jim is a member of Rock>, <Membership: Jim is a member of Roll>]
-
-
-### Forward Descriptors Tests ###
-
-# Due to complications with adding via an intermediary model,
-# the add method is not provided.
->>> rock.members.add(bob)
-Traceback (most recent call last):
-...
-AttributeError: 'ManyRelatedManager' object has no attribute 'add'
-
-# Create is also disabled as it suffers from the same problems as add.
->>> rock.members.create(name='Anne')
-Traceback (most recent call last):
-...
-AttributeError: Cannot use create() on a ManyToManyField which specifies an intermediary model. Use m2m_through.Membership's Manager instead.
-
-# Remove has similar complications, and is not provided either.
->>> rock.members.remove(jim)
-Traceback (most recent call last):
-...
-AttributeError: 'ManyRelatedManager' object has no attribute 'remove'
-
-# Here we back up the list of all members of Rock.
->>> backup = list(rock.members.all())
-
-# ...and we verify that it has worked.
->>> backup
-[<Person: Jane>, <Person: Jim>]
-
-# The clear function should still work.
->>> rock.members.clear()
-
-# Now there will be no members of Rock.
->>> rock.members.all()
-[]
-
-# Assignment should not work with models specifying a through model for many of
-# the same reasons as adding.
->>> rock.members = backup
-Traceback (most recent call last):
-...
-AttributeError: Cannot set values on a ManyToManyField which specifies an intermediary model. Use m2m_through.Membership's Manager instead.
-
-# Let's re-save those instances that we've cleared.
->>> m1.save()
->>> m2.save()
-
-# Verifying that those instances were re-saved successfully.
->>> rock.members.all()
-[<Person: Jane>, <Person: Jim>]
-
-
-### Reverse Descriptors Tests ###
-
-# Due to complications with adding via an intermediary model,
-# the add method is not provided.
->>> bob.group_set.add(rock)
-Traceback (most recent call last):
-...
-AttributeError: 'ManyRelatedManager' object has no attribute 'add'
-
-# Create is also disabled as it suffers from the same problems as add.
->>> bob.group_set.create(name='Funk')
-Traceback (most recent call last):
-...
-AttributeError: Cannot use create() on a ManyToManyField which specifies an intermediary model. Use m2m_through.Membership's Manager instead.
-
-# Remove has similar complications, and is not provided either.
->>> jim.group_set.remove(rock)
-Traceback (most recent call last):
-...
-AttributeError: 'ManyRelatedManager' object has no attribute 'remove'
-
-# Here we back up the list of all of Jim's groups.
->>> backup = list(jim.group_set.all())
->>> backup
-[<Group: Rock>, <Group: Roll>]
-
-# The clear function should still work.
->>> jim.group_set.clear()
-
-# Now Jim will be in no groups.
->>> jim.group_set.all()
-[]
-
-# Assignment should not work with models specifying a through model for many of
-# the same reasons as adding.
->>> jim.group_set = backup
-Traceback (most recent call last):
-...
-AttributeError: Cannot set values on a ManyToManyField which specifies an intermediary model. Use m2m_through.Membership's Manager instead.
-
-# Let's re-save those instances that we've cleared.
->>> m1.save()
->>> m4.save()
-
-# Verifying that those instances were re-saved successfully.
->>> jim.group_set.all()
-[<Group: Rock>, <Group: Roll>]
-
-### Custom Tests ###
-
-# Let's see if we can query through our second relationship.
->>> rock.custom_members.all()
-[]
-
-# We can query in the opposite direction as well.
->>> bob.custom.all()
-[]
-
-# Let's create some membership objects in this custom relationship.
->>> cm1 = CustomMembership.objects.create(person=bob, group=rock)
->>> cm2 = CustomMembership.objects.create(person=jim, group=rock)
-
-# If we get the number of people in Rock, it should be both Bob and Jim.
->>> rock.custom_members.all()
-[<Person: Bob>, <Person: Jim>]
-
-# Bob should only be in one custom group.
->>> bob.custom.all()
-[<Group: Rock>]
-
-# Let's make sure our new descriptors don't conflict with the FK related_name.
->>> bob.custom_person_related_name.all()
-[<CustomMembership: Bob is a member of Rock>]
-
-### SELF-REFERENTIAL TESTS ###
-
-# Let's first create a person who has no friends.
->>> tony = PersonSelfRefM2M.objects.create(name="Tony")
->>> tony.friends.all()
-[]
-
-# Now let's create another person for Tony to be friends with.
->>> chris = PersonSelfRefM2M.objects.create(name="Chris")
->>> f = Friendship.objects.create(first=tony, second=chris, date_friended=datetime.now())
-
-# Tony should now show that Chris is his friend.
->>> tony.friends.all()
-[<PersonSelfRefM2M: Chris>]
-
-# But we haven't established that Chris is Tony's Friend.
->>> chris.friends.all()
-[]
-
-# So let's do that now.
->>> f2 = Friendship.objects.create(first=chris, second=tony, date_friended=datetime.now())
-
-# Having added Chris as a friend, let's make sure that his friend set reflects
-# that addition.
->>> chris.friends.all()
-[<PersonSelfRefM2M: Tony>]
-
-# Chris gets mad and wants to get rid of all of his friends.
->>> chris.friends.clear()
-
-# Now he should not have any more friends.
->>> chris.friends.all()
-[]
-
-# Since this isn't a symmetrical relation, Tony's friend link still exists.
->>> tony.friends.all()
-[<PersonSelfRefM2M: Chris>]
-
-
-
-### QUERY TESTS ###
-
-# We can query for the related model by using its attribute name (members, in
-# this case).
->>> Group.objects.filter(members__name='Bob')
-[<Group: Roll>]
-
-# To query through the intermediary model, we specify its model name.
-# In this case, membership.
->>> Group.objects.filter(membership__invite_reason="She was just awesome.")
-[<Group: Rock>]
-
-# If we want to query in the reverse direction by the related model, use its
-# model name (group, in this case).
->>> Person.objects.filter(group__name="Rock")
-[<Person: Jane>, <Person: Jim>]
-
-# If the m2m field has specified a related_name, using that will work.
->>> Person.objects.filter(custom__name="Rock")
-[<Person: Bob>, <Person: Jim>]
-
-# To query through the intermediary model in the reverse direction, we again
-# specify its model name (membership, in this case).
->>> Person.objects.filter(membership__invite_reason="She was just awesome.")
-[<Person: Jane>]
-
-# Let's see all of the groups that Jane joined after 1 Jan 2005:
->>> Group.objects.filter(membership__date_joined__gt=datetime(2005, 1, 1), membership__person =jane)
-[<Group: Rock>]
-
-# Queries also work in the reverse direction: Now let's see all of the people
-# that have joined Rock since 1 Jan 2005:
->>> Person.objects.filter(membership__date_joined__gt=datetime(2005, 1, 1), membership__group=rock)
-[<Person: Jane>, <Person: Jim>]
-
-# Conceivably, queries through membership could return correct, but non-unique
-# querysets. To demonstrate this, we query for all people who have joined a
-# group after 2004:
->>> Person.objects.filter(membership__date_joined__gt=datetime(2004, 1, 1))
-[<Person: Jane>, <Person: Jim>, <Person: Jim>]
-
-# Jim showed up twice, because he joined two groups ('Rock', and 'Roll'):
->>> [(m.person.name, m.group.name) for m in
-... Membership.objects.filter(date_joined__gt=datetime(2004, 1, 1))]
-[(u'Jane', u'Rock'), (u'Jim', u'Rock'), (u'Jim', u'Roll')]
-
-# QuerySet's distinct() method can correct this problem.
->>> Person.objects.filter(membership__date_joined__gt=datetime(2004, 1, 1)).distinct()
-[<Person: Jane>, <Person: Jim>]
-"""}
View
343 tests/modeltests/m2m_through/tests.py
@@ -0,0 +1,343 @@
+from datetime import datetime
+from operator import attrgetter
+
+from django.test import TestCase
+
+from models import Person, Group, Membership, CustomMembership, \
+ TestNoDefaultsOrNulls, PersonSelfRefM2M, Friendship
+
+
+class M2mThroughTests(TestCase):
+ def setUp(self):
+ self.bob = Person.objects.create(name='Bob')
+ self.jim = Person.objects.create(name='Jim')
+ self.jane = Person.objects.create(name='Jane')
+ self.rock = Group.objects.create(name='Rock')
+ self.roll = Group.objects.create(name='Roll')
+
+ def test_m2m_through(self):
+ # We start out by making sure that the Group 'rock' has no members.
+ self.assertQuerysetEqual(
+ self.rock.members.all(),
+ []
+ )
+ # To make Jim a member of Group Rock, simply create a Membership object.
+ m1 = Membership.objects.create(person=self.jim, group=self.rock)
+ # We can do the same for Jane and Rock.
+ m2 = Membership.objects.create(person=self.jane, group=self.rock)
+ # Let's check to make sure that it worked. Jane and Jim should be members of Rock.
+ self.assertQuerysetEqual(
+ self.rock.members.all(), [
+ 'Jane',
+ 'Jim'
+ ],
+ attrgetter("name")
+ )
+ # Now we can add a bunch more Membership objects to test with.
+ m3 = Membership.objects.create(person=self.bob, group=self.roll)
+ m4 = Membership.objects.create(person=self.jim, group=self.roll)
+ m5 = Membership.objects.create(person=self.jane, group=self.roll)
+ # We can get Jim's Group membership as with any ForeignKey.
+ self.assertQuerysetEqual(
+ self.jim.group_set.all(), [
+ 'Rock',
+ 'Roll'
+ ],
+ attrgetter("name")
+ )
+ # Querying the intermediary model works like normal.
+ self.assertEqual(
+ repr(Membership.objects.get(person=self.jane, group=self.rock)),
+ '<Membership: Jane is a member of Rock>'
+ )
+ # It's not only get that works. Filter works like normal as well.
+ self.assertQuerysetEqual(
+ Membership.objects.filter(person=self.jim), [
+ '<Membership: Jim is a member of Rock>',
+ '<Membership: Jim is a member of Roll>'
+ ]
+ )
+ self.rock.members.clear()
+ # Now there will be no members of Rock.
+ self.assertQuerysetEqual(
+ self.rock.members.all(),
+ []
+ )
+
+
+
+ def test_forward_descriptors(self):
+ # Due to complications with adding via an intermediary model,
+ # the add method is not provided.
+ self.assertRaises(AttributeError, lambda: self.rock.members.add(self.bob))
+ # Create is also disabled as it suffers from the same problems as add.
+ self.assertRaises(AttributeError, lambda: self.rock.members.create(name='Anne'))
+ # Remove has similar complications, and is not provided either.
+ self.assertRaises(AttributeError, lambda: self.rock.members.remove(self.jim))
+
+ m1 = Membership.objects.create(person=self.jim, group=self.rock)
+ m2 = Membership.objects.create(person=self.jane, group=self.rock)
+
+ # Here we back up the list of all members of Rock.
+ backup = list(self.rock.members.all())
+ # ...and we verify that it has worked.
+ self.assertEqual(
+ [p.name for p in backup],
+ ['Jane', 'Jim']
+ )
+ # The clear function should still work.
+ self.rock.members.clear()
+ # Now there will be no members of Rock.
+ self.assertQuerysetEqual(
+ self.rock.members.all(),
+ []
+ )
+
+ # Assignment should not work with models specifying a through model for many of
+ # the same reasons as adding.
+ self.assertRaises(AttributeError, setattr, self.rock, "members", backup)
+ # Let's re-save those instances that we've cleared.
+ m1.save()
+ m2.save()
+ # Verifying that those instances were re-saved successfully.
+ self.assertQuerysetEqual(
+ self.rock.members.all(),[
+ 'Jane',
+ 'Jim'
+ ],
+ attrgetter("name")
+ )
+
+ def test_reverse_descriptors(self):
+ # Due to complications with adding via an intermediary model,
+ # the add method is not provided.
+ self.assertRaises(AttributeError, lambda: self.bob.group_set.add(self.rock))
+ # Create is also disabled as it suffers from the same problems as add.
+ self.assertRaises(AttributeError, lambda: self.bob.group_set.create(name="funk"))
+ # Remove has similar complications, and is not provided either.
+ self.assertRaises(AttributeError, lambda: self.jim.group_set.remove(self.rock))
+
+ m1 = Membership.objects.create(person=self.jim, group=self.rock)
+ m2 = Membership.objects.create(person=self.jim, group=self.roll)
+
+ # Here we back up the list of all of Jim's groups.
+ backup = list(self.jim.group_set.all())
+ self.assertEqual(
+ [g.name for g in backup],
+ ['Rock', 'Roll']
+ )
+ # The clear function should still work.
+ self.jim.group_set.clear()
+ # Now Jim will be in no groups.
+ self.assertQuerysetEqual(
+ self.jim.group_set.all(),
+ []
+ )
+ # Assignment should not work with models specifying a through model for many of
+ # the same reasons as adding.
+ self.assertRaises(AttributeError, setattr, self.jim, "group_set", backup)
+ # Let's re-save those instances that we've cleared.
+
+ m1.save()
+ m2.save()
+ # Verifying that those instances were re-saved successfully.
+ self.assertQuerysetEqual(
+ self.jim.group_set.all(),[
+ 'Rock',
+ 'Roll'
+ ],
+ attrgetter("name")
+ )
+
+ def test_custom_tests(self):
+ # Let's see if we can query through our second relationship.
+ self.assertQuerysetEqual(
+ self.rock.custom_members.all(),
+ []
+ )
+ # We can query in the opposite direction as well.
+ self.assertQuerysetEqual(
+ self.bob.custom.all(),
+ []
+ )
+
+ cm1 = CustomMembership.objects.create(person=self.bob, group=self.rock)
+ cm2 = CustomMembership.objects.create(person=self.jim, group=self.rock)
+
+ # If we get the number of people in Rock, it should be both Bob and Jim.
+ self.assertQuerysetEqual(
+ self.rock.custom_members.all(),[
+ 'Bob',
+ 'Jim'
+ ],
+ attrgetter("name")
+ )
+ # Bob should only be in one custom group.
+ self.assertQuerysetEqual(
+ self.bob.custom.all(),[
+ 'Rock'
+ ],
+ attrgetter("name")
+ )
+ # Let's make sure our new descriptors don't conflict with the FK related_name.
+ self.assertQuerysetEqual(
+ self.bob.custom_person_related_name.all(),[
+ '<CustomMembership: Bob is a member of Rock>'
+ ]
+ )
+
+ def test_self_referential_tests(self):
+ # Let's first create a person who has no friends.
+ tony = PersonSelfRefM2M.objects.create(name="Tony")
+ self.assertQuerysetEqual(
+ tony.friends.all(),
+ []
+ )
+
+ chris = PersonSelfRefM2M.objects.create(name="Chris")
+ f = Friendship.objects.create(first=tony, second=chris, date_friended=datetime.now())
+
+ # Tony should now show that Chris is his friend.
+ self.assertQuerysetEqual(
+ tony.friends.all(),[
+ 'Chris'
+ ],
+ attrgetter("name")
+ )
+ # But we haven't established that Chris is Tony's Friend.
+ self.assertQuerysetEqual(
+ chris.friends.all(),
+ []
+ )
+ f2 = Friendship.objects.create(first=chris, second=tony, date_friended=datetime.now())
+
+ # Having added Chris as a friend, let's make sure that his friend set reflects
+ # that addition.
+ self.assertQuerysetEqual(
+ chris.friends.all(),[
+ 'Tony'
+ ],
+ attrgetter("name")
+ )
+
+ # Chris gets mad and wants to get rid of all of his friends.
+ chris.friends.clear()
+ # Now he should not have any more friends.
+ self.assertQuerysetEqual(
+ chris.friends.all(),
+ []
+ )
+ # Since this isn't a symmetrical relation, Tony's friend link still exists.
+ self.assertQuerysetEqual(
+ tony.friends.all(),[
+ 'Chris'
+ ],
+ attrgetter("name")
+ )
+
+ def test_query_tests(self):
+ m1 = Membership.objects.create(person=self.jim, group=self.rock)
+ m2 = Membership.objects.create(person=self.jane, group=self.rock)
+ m3 = Membership.objects.create(person=self.bob, group=self.roll)
+ m4 = Membership.objects.create(person=self.jim, group=self.roll)
+ m5 = Membership.objects.create(person=self.jane, group=self.roll)
+
+ m2.invite_reason = "She was just awesome."
+ m2.date_joined = datetime(2006, 1, 1)
+ m2.save()
+ m3.date_joined = datetime(2004, 1, 1)
+ m3.save()
+ m5.date_joined = datetime(2004, 1, 1)
+ m5.save()
+
+ # We can query for the related model by using its attribute name (members, in
+ # this case).
+ self.assertQuerysetEqual(
+ Group.objects.filter(members__name='Bob'),[
+ 'Roll'
+ ],
+ attrgetter("name")
+ )
+
+ # To query through the intermediary model, we specify its model name.
+ # In this case, membership.
+ self.assertQuerysetEqual(
+ Group.objects.filter(membership__invite_reason="She was just awesome."),[
+ 'Rock'
+ ],
+ attrgetter("name")
+ )
+
+ # If we want to query in the reverse direction by the related model, use its
+ # model name (group, in this case).
+ self.assertQuerysetEqual(
+ Person.objects.filter(group__name="Rock"),[
+ 'Jane',
+ 'Jim'
+ ],
+ attrgetter("name")
+ )
+
+ cm1 = CustomMembership.objects.create(person=self.bob, group=self.rock)
+ cm2 = CustomMembership.objects.create(person=self.jim, group=self.rock)
+ # If the m2m field has specified a related_name, using that will work.
+ self.assertQuerysetEqual(
+ Person.objects.filter(custom__name="Rock"),[
+ 'Bob',
+ 'Jim'
+ ],
+ attrgetter("name")
+ )
+
+ # To query through the intermediary model in the reverse direction, we again
+ # specify its model name (membership, in this case).
+ self.assertQuerysetEqual(
+ Person.objects.filter(membership__invite_reason="She was just awesome."),[
+ 'Jane'
+ ],
+ attrgetter("name")
+ )
+
+ # Let's see all of the groups that Jane joined after 1 Jan 2005:
+ self.assertQuerysetEqual(
+ Group.objects.filter(membership__date_joined__gt=datetime(2005, 1, 1), membership__person=self.jane),[
+ 'Rock'
+ ],
+ attrgetter("name")
+ )
+
+ # Queries also work in the reverse direction: Now let's see all of the people
+ # that have joined Rock since 1 Jan 2005:
+ self.assertQuerysetEqual(
+ Person.objects.filter(membership__date_joined__gt=datetime(2005, 1, 1), membership__group=self.rock),[
+ 'Jane',
+ 'Jim'
+ ],
+ attrgetter("name")
+ )
+
+ # Conceivably, queries through membership could return correct, but non-unique
+ # querysets. To demonstrate this, we query for all people who have joined a
+ # group after 2004:
+ self.assertQuerysetEqual(
+ Person.objects.filter(membership__date_joined__gt=datetime(2004, 1, 1)),[
+ 'Jane',
+ 'Jim',
+ 'Jim'
+ ],
+ attrgetter("name")
+ )
+
+ # Jim showed up twice, because he joined two groups ('Rock', and 'Roll'):
+ self.assertEqual(
+ [(m.person.name, m.group.name) for m in Membership.objects.filter(date_joined__gt=datetime(2004, 1, 1))],
+ [(u'Jane', u'Rock'), (u'Jim', u'Rock'), (u'Jim', u'Roll')]
+ )
+ # QuerySet's distinct() method can correct this problem.
+ self.assertQuerysetEqual(
+ Person.objects.filter(membership__date_joined__gt=datetime(2004, 1, 1)).distinct(),[
+ 'Jane',
+ 'Jim'
+ ],
+ attrgetter("name")
+ )
Please sign in to comment.
Something went wrong with that request. Please try again.