Browse Source

Fixed #24289 -- Reversed usage of Field.many_to_one and one_to_many.

Thanks Carl Meyer and Tim Graham for the reviews and to all involved
in the discussion.
Loic Bistuer 10 years ago
parent
commit
18c0aaa912

+ 1 - 1
django/contrib/admin/utils.py

@@ -296,7 +296,7 @@ def _get_non_gfk_field(opts, name):
     "not found" by get_field(). This could likely be cleaned up.
     """
     field = opts.get_field(name)
-    if field.is_relation and field.one_to_many and not field.related_model:
+    if field.is_relation and field.many_to_one and not field.related_model:
         raise FieldDoesNotExist()
     return field
 

+ 4 - 4
django/contrib/contenttypes/fields.py

@@ -27,8 +27,8 @@ class GenericForeignKey(object):
 
     is_relation = True
     many_to_many = False
-    many_to_one = False
-    one_to_many = True
+    many_to_one = True
+    one_to_many = False
     one_to_one = False
     related_model = None
 
@@ -269,8 +269,8 @@ class GenericRelation(ForeignObject):
     auto_created = False
 
     many_to_many = False
-    many_to_one = True
-    one_to_many = False
+    many_to_one = False
+    one_to_many = True
     one_to_one = False
 
     rel_class = GenericRel

+ 1 - 1
django/db/models/deletion.py

@@ -65,7 +65,7 @@ def get_candidate_relations_to_delete(opts):
     # N-N  (i.e., many-to-many) relations aren't candidates for deletion.
     return (
         f for f in candidate_model_fields
-        if f.auto_created and not f.concrete and (f.one_to_one or f.many_to_one)
+        if f.auto_created and not f.concrete and (f.one_to_one or f.one_to_many)
     )
 
 

+ 4 - 4
django/db/models/fields/related.py

@@ -1528,8 +1528,8 @@ class ManyToManyRel(ForeignObjectRel):
 class ForeignObject(RelatedField):
     # Field flags
     many_to_many = False
-    many_to_one = False
-    one_to_many = True
+    many_to_one = True
+    one_to_many = False
     one_to_one = False
 
     requires_unique_target = True
@@ -1841,8 +1841,8 @@ class ForeignObject(RelatedField):
 class ForeignKey(ForeignObject):
     # Field flags
     many_to_many = False
-    many_to_one = False
-    one_to_many = True
+    many_to_one = True
+    one_to_many = False
     one_to_one = False
 
     rel_class = ManyToOneRel

+ 3 - 3
django/db/models/options.py

@@ -388,9 +388,9 @@ class Options(object):
         # and all the models may not have been loaded yet; we don't want to cache
         # the string reference to the related_model.
         is_not_an_m2m_field = lambda f: not (f.is_relation and f.many_to_many)
-        is_not_a_generic_relation = lambda f: not (f.is_relation and f.many_to_one)
+        is_not_a_generic_relation = lambda f: not (f.is_relation and f.one_to_many)
         is_not_a_generic_foreign_key = lambda f: not (
-            f.is_relation and f.one_to_many and not (hasattr(f.rel, 'to') and f.rel.to)
+            f.is_relation and f.many_to_one and not (hasattr(f.rel, 'to') and f.rel.to)
         )
         return make_immutable_fields_list(
             "fields",
@@ -564,7 +564,7 @@ class Options(object):
         for field in fields:
             # For backwards compatibility GenericForeignKey should not be
             # included in the results.
-            if field.is_relation and field.one_to_many and field.related_model is None:
+            if field.is_relation and field.many_to_one and field.related_model is None:
                 continue
 
             names.add(field.name)

+ 10 - 10
docs/ref/models/fields.txt

@@ -1810,16 +1810,6 @@ relation. These attribute are present on all fields; however, they will only
 have meaningful values if the field is a relation type
 (:attr:`Field.is_relation=True <Field.is_relation>`).
 
-.. attribute:: Field.one_to_many
-
-    Boolean flag that is ``True`` if the field has a one-to-many relation, such
-    as a ``ForeignKey``; ``False`` otherwise.
-
-.. attribute:: Field.one_to_one
-
-    Boolean flag that is ``True`` if the field has a one-to-one relation, such
-    as a ``OneToOneField``; ``False`` otherwise.
-
 .. attribute:: Field.many_to_many
 
     Boolean flag that is ``True`` if the field has a many-to-many relation;
@@ -1829,9 +1819,19 @@ have meaningful values if the field is a relation type
 .. attribute:: Field.many_to_one
 
     Boolean flag that is ``True`` if the field has a many-to-one relation, such
+    as a ``ForeignKey``; ``False`` otherwise.
+
+.. attribute:: Field.one_to_many
+
+    Boolean flag that is ``True`` if the field has a one-to-many relation, such
     as a ``GenericRelation`` or the reverse of a ``ForeignKey``; ``False``
     otherwise.
 
+.. attribute:: Field.one_to_one
+
+    Boolean flag that is ``True`` if the field has a one-to-one relation, such
+    as a ``OneToOneField``; ``False`` otherwise.
+
 .. attribute:: Field.related_model
 
     Points to the model the field relates to. For example, ``Author`` in

+ 5 - 5
docs/ref/models/meta.txt

@@ -213,7 +213,7 @@ can be made to convert your code to the new API:
           for f in MyModel._meta.get_fields()
           if not f.is_relation
               or f.one_to_one
-              or (f.one_to_many and f.related_model)
+              or (f.many_to_one and f.related_model)
       ]
 
 * ``MyModel._meta.get_concrete_fields_with_model()``::
@@ -224,7 +224,7 @@ can be made to convert your code to the new API:
           if f.concrete and (
               not f.is_relation
               or f.one_to_one
-              or (f.one_to_many and f.related_model)
+              or (f.many_to_one and f.related_model)
           )
       ]
 
@@ -240,7 +240,7 @@ can be made to convert your code to the new API:
 
       [
           f for f in MyModel._meta.get_fields()
-          if f.many_to_one and f.auto_created
+          if f.one_to_many and f.auto_created
       ]
 
 * ``MyModel._meta.get_all_related_objects_with_model()``::
@@ -248,7 +248,7 @@ can be made to convert your code to the new API:
       [
           (f, f.model if f.model != MyModel else None)
           for f in MyModel._meta.get_fields()
-          if f.many_to_one and f.auto_created
+          if f.one_to_many and f.auto_created
       ]
 
 * ``MyModel._meta.get_all_related_many_to_many_objects()``::
@@ -274,7 +274,7 @@ can be made to convert your code to the new API:
           for field in MyModel._meta.get_fields()
           # For complete backwards compatibility, you may want to exclude
           # GenericForeignKey from the results.
-          if not (field.one_to_many and field.related_model is None)
+          if not (field.many_to_one and field.related_model is None)
       )))
 
   This provides a 100% backwards compatible replacement, ensuring that both

+ 6 - 6
tests/model_fields/test_field_flags.py

@@ -31,22 +31,22 @@ RELATION_FIELDS = (
     GenericRelation,
 )
 
-ONE_TO_MANY_CLASSES = {
+MANY_TO_MANY_CLASSES = {
+    ManyToManyField,
+}
+
+MANY_TO_ONE_CLASSES = {
     ForeignObject,
     ForeignKey,
     GenericForeignKey,
 }
 
-MANY_TO_ONE_CLASSES = {
+ONE_TO_MANY_CLASSES = {
     ForeignObjectRel,
     ManyToOneRel,
     GenericRelation,
 }
 
-MANY_TO_MANY_CLASSES = {
-    ManyToManyField,
-}
-
 ONE_TO_ONE_CLASSES = {
     OneToOneField,
 }