Ticket #14820: 14820-textfield-generic-relations-r14785.diff

File 14820-textfield-generic-relations-r14785.diff, 8.1 KB (added by Tai Lee, 13 years ago)
  • docs/ref/contrib/contenttypes.txt

     
    6060.. class:: models.ContentType
    6161
    6262    Each instance of :class:`~django.contrib.contenttypes.models.ContentType`
    63     has three fields which, taken together, uniquely describe an installed model:
     63    has three fields which, taken together, uniquely describe an installed
     64    model:
    6465
    6566    .. attribute:: models.ContentType.app_label
    6667
    6768        The name of the application the model is part of. This is taken from
    68         the :attr:`app_label` attribute of the model, and includes only the *last*
    69         part of the application's Python import path;
    70         "django.contrib.contenttypes", for example, becomes an :attr:`app_label`
    71         of "contenttypes".
     69        the :attr:`app_label` attribute of the model, and includes only the
     70        *last* part of the application's Python import path;
     71        "django.contrib.contenttypes", for example, becomes an
     72        :attr:`app_label` of "contenttypes".
    7273
    7374    .. attribute:: models.ContentType.model
    7475
     
    105106
    106107    Each :class:`~django.contrib.contenttypes.models.ContentType` instance has
    107108    methods that allow you to get from a
    108     :class:`~django.contrib.contenttypes.models.ContentType` instance to the model
    109     it represents, or to retrieve objects from that model:
     109    :class:`~django.contrib.contenttypes.models.ContentType` instance to the
     110    model it represents, or to retrieve objects from that model:
    110111
    111112.. method:: models.ContentType.get_object_for_this_type(**kwargs)
    112113
     
    139140
    140141Together,
    141142:meth:`~django.contrib.contenttypes.models.ContentType.get_object_for_this_type`
    142 and :meth:`~django.contrib.contenttypes.models.ContentType.model_class`
    143 enable two extremely important use cases:
     143and :meth:`~django.contrib.contenttypes.models.ContentType.model_class` enable
     144two extremely important use cases:
    144145
    145146    1. Using these methods, you can write high-level generic code that
    146        performs queries on any installed model -- instead of importing and using
    147        a single specific model class, you can pass an ``app_label`` and
    148        ``model`` into a :class:`~django.contrib.contenttypes.models.ContentType`
    149        lookup at runtime, and then work with the model class or retrieve objects
    150        from it.
     147       performs queries on any installed model -- instead of importing and
     148       using a single specific model class, you can pass an ``app_label`` and
     149       ``model`` into a
     150       :class:`~django.contrib.contenttypes.models.ContentType` lookup at
     151       runtime, and then work with the model class or retrieve objects from it.
    151152
    152153    2. You can relate another model to
    153154       :class:`~django.contrib.contenttypes.models.ContentType` as a way of
     
    187188        :class:`~django.contrib.contenttypes.models.ContentType` instance
    188189        representing that model.
    189190
    190 The :meth:`~models.ContentTypeManager.get_for_model()` method is especially useful when you know you
    191 need to work with a :class:`ContentType <django.contrib.contenttypes.models.ContentType>` but don't want to go to the
    192 trouble of obtaining the model's metadata to perform a manual lookup::
     191The :meth:`~models.ContentTypeManager.get_for_model()` method is especially
     192useful when you know you need to work with a
     193:class:`ContentType <django.contrib.contenttypes.models.ContentType>` but don't
     194want to go to the trouble of obtaining the model's metadata to perform a manual
     195lookup::
    193196
    194197    >>> from django.contrib.auth.models import User
    195198    >>> user_type = ContentType.objects.get_for_model(User)
     
    218221    class TaggedItem(models.Model):
    219222        tag = models.SlugField()
    220223        content_type = models.ForeignKey(ContentType)
    221         object_id = models.PositiveIntegerField()
     224        object_id = models.IntegerField()
    222225        content_object = generic.GenericForeignKey('content_type', 'object_id')
    223226
    224227        def __unicode__(self):
     
    237240    1. Give your model a :class:`~django.db.models.fields.related.ForeignKey`
    238241       to :class:`~django.contrib.contenttypes.models.ContentType`.
    239242
    240     2. Give your model a field that can store a primary-key value from the
    241        models you'll be relating to. (For most models, this means an
    242        :class:`~django.db.models.fields.IntegerField` or
    243        :class:`~django.db.models.fields.PositiveIntegerField`.)
     243    2. Give your model a field that can store primary key values from the
     244       models you'll be relating to. For most models, this means an
     245       :class:`~django.db.models.fields.IntegerField`, which is the default.
     246       The usual name for this field is "object_id".
    244247
    245        This field must be of the same type as the primary key of the models
    246        that will be involved in the generic relation. For example, if you use
    247        :class:`~django.db.models.fields.IntegerField`, you won't be able to
    248        form a generic relation with a model that uses a
    249        :class:`~django.db.models.fields.CharField` as a primary key.
     248       .. versionchanged:: 1.3
    250249
     250       .. admonition:: Related model primary key field type compatibility
     251
     252           The "object_id" field doesn't have to be the same type as the
     253           primary key fields on related models, but their primary key values
     254           must be coercible to the same type as the "object_id" field by its
     255           :meth:`get_db_prep_value` method.
     256
     257           For example, if you want to allow generic relations to your model
     258           from other models with either
     259           :class:`~django.db.models.fields.IntegerField` or
     260           :class:`~django.db.models.fields.CharField` primary key fields, you
     261           can use :class:`~django.db.models.fields.CharField` for the
     262           "object_id" field in your model, because integers can be coerced to
     263           strings by the
     264           :meth:`~django.db.models.fields.CharField.get_db_prep_value` method.
     265
     266           For maximum flexibility when you don't know which models will be
     267           related back to yours with generic relations, you can use
     268           :class:`~django.db.models.fields.TextField` which doesn't have a
     269           maximum length defined and should work in generic relations with
     270           any models whose primary keys can be coerced to string.
     271
     272           However, keep in mind that text database columns can use more
     273           memory, be less performant or have indexing woes, depending on the
     274           database and its configuration. If you are certain that all related
     275           models will use the one type of primary key field, it's better to
     276           use the same type in your model, too.
     277
    251278    3. Give your model a
    252279       :class:`~django.contrib.contenttypes.generic.GenericForeignKey`, and
    253280       pass it the names of the two fields described above. If these fields
     
    311338``object_primary_key`` to create its generic foreign key, then a
    312339``GenericRelation`` back to it would need to be defined like so::
    313340
    314     tags = generic.GenericRelation(TaggedItem, content_type_field='content_type_fk', object_id_field='object_primary_key')
     341    tags = generic.GenericRelation(TaggedItem,
     342                                   content_type_field='content_type_fk',
     343                                   object_id_field='object_primary_key')
    315344
    316345Of course, if you don't add the reverse relationship, you can do the
    317346same types of lookups manually::
     
    362391    Bookmark.objects.aggregate(Count('tags'))
    363392
    364393This will not work correctly, however. The generic relation adds extra filters
    365 to the queryset to ensure the correct content type, but the ``aggregate`` method
    366 doesn't take them into account. For now, if you need aggregates on generic
    367 relations, you'll need to calculate them without using the aggregation API.
     394to the queryset to ensure the correct content type, but the ``aggregate``
     395method doesn't take them into account. For now, if you need aggregates on
     396generic relations, you'll need to calculate them without using the aggregation
     397API.
    368398
    369399Generic relations in forms and admin
    370400------------------------------------
Back to Top