Author: ramiro
Date: 2010-11-14 17:36:40 -0600 (Sun, 14 Nov 2010)
New Revision: 14565

Modified:
   django/branches/releases/1.2.X/django/core/management/validation.py
   django/branches/releases/1.2.X/django/utils/itercompat.py
   django/branches/releases/1.2.X/tests/modeltests/invalid_models/models.py
Log:
[1.2.X] Fixed #3055 -- Validate that models target of a GenericRelation have a 
GenericForeignKey field.

Thanks jason for diagnosing the problem and Marcos Moyano for the patch.

Backport of [14563] from trunk

Modified: django/branches/releases/1.2.X/django/core/management/validation.py
===================================================================
--- django/branches/releases/1.2.X/django/core/management/validation.py 
2010-11-14 23:35:16 UTC (rev 14564)
+++ django/branches/releases/1.2.X/django/core/management/validation.py 
2010-11-14 23:36:40 UTC (rev 14565)
@@ -1,7 +1,14 @@
 import sys
+
+from django.contrib.contenttypes.generic import GenericForeignKey, 
GenericRelation
 from django.core.management.color import color_style
 from django.utils.itercompat import is_iterable
 
+try:
+    any
+except NameError:
+    from django.utils.itercompat import any
+
 class ModelErrorCollection:
     def __init__(self, outfile=sys.stdout):
         self.errors = []
@@ -216,6 +223,12 @@
                 e.add(opts, "'%s' specifies an m2m relation through model %s, "
                     "which has not been installed" % (f.name, f.rel.through)
                 )
+            elif isinstance(f, GenericRelation):
+                if not any([isinstance(vfield, GenericForeignKey) for vfield 
in f.rel.to._meta.virtual_fields]):
+                    e.add(opts, "Model '%s' must have a GenericForeignKey in "
+                        "order to create a GenericRelation that points to it."
+                        % f.rel.to.__name__
+                    )
 
             rel_opts = f.rel.to._meta
             rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name()

Modified: django/branches/releases/1.2.X/django/utils/itercompat.py
===================================================================
--- django/branches/releases/1.2.X/django/utils/itercompat.py   2010-11-14 
23:35:16 UTC (rev 14564)
+++ django/branches/releases/1.2.X/django/utils/itercompat.py   2010-11-14 
23:36:40 UTC (rev 14565)
@@ -37,3 +37,9 @@
         if not item:
             return False
     return True
+
+def any(iterable):
+    for item in iterable:
+        if item:
+            return True
+    return False

Modified: 
django/branches/releases/1.2.X/tests/modeltests/invalid_models/models.py
===================================================================
--- django/branches/releases/1.2.X/tests/modeltests/invalid_models/models.py    
2010-11-14 23:35:16 UTC (rev 14564)
+++ django/branches/releases/1.2.X/tests/modeltests/invalid_models/models.py    
2010-11-14 23:36:40 UTC (rev 14565)
@@ -4,6 +4,7 @@
 This example exists purely to point out errors in models.
 """
 
+from django.contrib.contenttypes import generic
 from django.db import models
 
 class FieldErrors(models.Model):
@@ -210,6 +211,21 @@
     class Meta:
         ordering = ("does_not_exist",)
 
+class Tag(models.Model):
+   name = models.CharField("name", max_length=20)
+
+class TaggedObject(models.Model):
+   object_id = models.PositiveIntegerField("Object ID")
+   tag = models.ForeignKey(Tag)
+   content_object = generic.GenericForeignKey()
+
+class UserTaggedObject(models.Model):
+   object_tag = models.ForeignKey(TaggedObject)
+
+class ArticleAttachment(models.Model):
+   tags = generic.GenericRelation(TaggedObject)
+   user_tags = generic.GenericRelation(UserTaggedObject)
+
 model_errors = """invalid_models.fielderrors: "charfield": CharFields require 
a "max_length" attribute that is a positive integer.
 invalid_models.fielderrors: "charfield2": CharFields require a "max_length" 
attribute that is a positive integer.
 invalid_models.fielderrors: "charfield3": CharFields require a "max_length" 
attribute that is a positive integer.
@@ -315,4 +331,5 @@
 invalid_models.nonuniquefktarget1: Field 'bad' under model 'FKTarget' must 
have a unique=True constraint.
 invalid_models.nonuniquefktarget2: Field 'bad' under model 'FKTarget' must 
have a unique=True constraint.
 invalid_models.nonexistingorderingwithsingleunderscore: "ordering" refers to 
"does_not_exist", a field that doesn't exist.
+invalid_models.articleattachment: Model 'UserTaggedObject' must have a 
GenericForeignKey in order to create a GenericRelation that points to it.
 """

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-upda...@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to