summaryrefslogtreecommitdiff
path: root/tests/modeltests/generic_relations/models.py
diff options
context:
space:
mode:
authorJoseph Kocherhans <joseph@jkocherhans.com>2006-06-19 15:23:57 +0000
committerJoseph Kocherhans <joseph@jkocherhans.com>2006-06-19 15:23:57 +0000
commitadf4b9311d5d64a2bdd58da50271c121ea22e397 (patch)
treea69b3b023595cf1ce67a14c4c1ecd3290d94088e /tests/modeltests/generic_relations/models.py
parente976ed1f7910fad03704f88853c5c5b36cbab134 (diff)
downloaddjango-attic/multi-auth.tar.gz
multi-auth: Merged to [3151]archive/attic/multi-authattic/multi-auth
git-svn-id: http://code.djangoproject.com/svn/django/branches/multi-auth@3152 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/modeltests/generic_relations/models.py')
-rw-r--r--tests/modeltests/generic_relations/models.py108
1 files changed, 108 insertions, 0 deletions
diff --git a/tests/modeltests/generic_relations/models.py b/tests/modeltests/generic_relations/models.py
new file mode 100644
index 0000000000..a9a775ad6e
--- /dev/null
+++ b/tests/modeltests/generic_relations/models.py
@@ -0,0 +1,108 @@
+"""
+33. Generic relations
+
+Generic relations let an object have a foreign key to any object through a
+content-type/object-id field. A generic foreign key can point to any object,
+be it animal, vegetable, or mineral.
+
+The cannonical example is tags (although this example implementation is *far*
+from complete).
+"""
+
+from django.db import models
+from django.contrib.contenttypes.models import ContentType
+
+class TaggedItem(models.Model):
+ """A tag on an item."""
+ tag = models.SlugField()
+ content_type = models.ForeignKey(ContentType)
+ object_id = models.PositiveIntegerField()
+
+ content_object = models.GenericForeignKey()
+
+ class Meta:
+ ordering = ["tag"]
+
+ def __str__(self):
+ return self.tag
+
+class Animal(models.Model):
+ common_name = models.CharField(maxlength=150)
+ latin_name = models.CharField(maxlength=150)
+
+ tags = models.GenericRelation(TaggedItem)
+
+ def __str__(self):
+ return self.common_name
+
+class Vegetable(models.Model):
+ name = models.CharField(maxlength=150)
+ is_yucky = models.BooleanField(default=True)
+
+ tags = models.GenericRelation(TaggedItem)
+
+ def __str__(self):
+ return self.name
+
+class Mineral(models.Model):
+ name = models.CharField(maxlength=150)
+ hardness = models.PositiveSmallIntegerField()
+
+ # note the lack of an explicit GenericRelation here...
+
+ def __str__(self):
+ return self.name
+
+API_TESTS = """
+# Create the world in 7 lines of code...
+>>> lion = Animal(common_name="Lion", latin_name="Panthera leo")
+>>> platypus = Animal(common_name="Platypus", latin_name="Ornithorhynchus anatinus")
+>>> eggplant = Vegetable(name="Eggplant", is_yucky=True)
+>>> bacon = Vegetable(name="Bacon", is_yucky=False)
+>>> quartz = Mineral(name="Quartz", hardness=7)
+>>> for o in (lion, platypus, eggplant, bacon, quartz):
+... o.save()
+
+# Objects with declared GenericRelations can be tagged directly -- the API
+# mimics the many-to-many API
+>>> lion.tags.create(tag="yellow")
+<TaggedItem: yellow>
+>>> lion.tags.create(tag="hairy")
+<TaggedItem: hairy>
+>>> bacon.tags.create(tag="fatty")
+<TaggedItem: fatty>
+>>> bacon.tags.create(tag="salty")
+<TaggedItem: salty>
+
+>>> lion.tags.all()
+[<TaggedItem: hairy>, <TaggedItem: yellow>]
+>>> bacon.tags.all()
+[<TaggedItem: fatty>, <TaggedItem: salty>]
+
+# You can easily access the content object like a foreign key
+>>> t = TaggedItem.objects.get(tag="salty")
+>>> t.content_object
+<Vegetable: Bacon>
+
+# Recall that the Mineral class doesn't have an explicit GenericRelation
+# defined. That's OK since you can create TaggedItems explicitally.
+>>> tag1 = TaggedItem(content_object=quartz, tag="shiny")
+>>> tag2 = TaggedItem(content_object=quartz, tag="clearish")
+>>> tag1.save()
+>>> tag2.save()
+
+# However, not having the convience takes a small toll when it comes
+# to do lookups
+>>> from django.contrib.contenttypes.models import ContentType
+>>> ctype = ContentType.objects.get_for_model(quartz)
+>>> TaggedItem.objects.filter(content_type__pk=ctype.id, object_id=quartz.id)
+[<TaggedItem: clearish>, <TaggedItem: shiny>]
+
+# You can set a generic foreign key in the way you'd expect
+>>> tag1.content_object = platypus
+>>> tag1.save()
+>>> platypus.tags.all()
+[<TaggedItem: shiny>]
+>>> TaggedItem.objects.filter(content_type__pk=ctype.id, object_id=quartz.id)
+[<TaggedItem: clearish>]
+""" \ No newline at end of file