summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2014-01-22 01:43:33 -0500
committerSimon Charette <charette.s@gmail.com>2014-01-26 14:42:30 -0500
commit10e3faf191d8f230dde8534d1c8fad8c8717816e (patch)
tree26d597787a0a22f0f11b1d1e0daf0c3b1feb5805 /docs
parentc3881944e8651ad98e29561154186e87928ca319 (diff)
Fixed #19774 -- Deprecated the contenttypes.generic module.
It contained models, forms and admin objects causing undesirable import side effects. Refs #16368. Thanks to Ramiro, Carl and Loïc for the review.
Diffstat (limited to 'docs')
-rw-r--r--docs/ref/contrib/admin/index.txt14
-rw-r--r--docs/ref/contrib/comments/models.txt4
-rw-r--r--docs/ref/contrib/contenttypes.txt136
-rw-r--r--docs/ref/models/querysets.txt4
-rw-r--r--docs/releases/1.4-alpha-1.txt3
-rw-r--r--docs/releases/1.4-beta-1.txt3
-rw-r--r--docs/releases/1.4.txt3
-rw-r--r--docs/releases/1.6.txt8
-rw-r--r--docs/releases/1.7.txt19
9 files changed, 123 insertions, 71 deletions
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index 281ea4674b..14d2a69d7f 100644
--- a/docs/ref/contrib/admin/index.txt
+++ b/docs/ref/contrib/admin/index.txt
@@ -2187,30 +2187,32 @@ It is possible to use an inline with generically related objects. Let's say
you have the following models::
from django.db import models
+ from django.contrib.contenttypes.fields import GenericForeignKey
class Image(models.Model):
image = models.ImageField(upload_to="images")
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
- content_object = generic.GenericForeignKey("content_type", "object_id")
+ content_object = GenericForeignKey("content_type", "object_id")
class Product(models.Model):
name = models.CharField(max_length=100)
If you want to allow editing and creating ``Image`` instance on the ``Product``
-add/change views you can use ``GenericTabularInline`` or
-``GenericStackedInline`` (both subclasses of ``GenericInlineModelAdmin``)
-provided by ``django.contrib.contenttypes.generic``, they implement tabular and
+add/change views you can use :class:`~django.contrib.contenttypes.admin.GenericTabularInline`
+or :class:`~django.contrib.contenttypes.admin.GenericStackedInline` (both
+subclasses of :class:`~django.contrib.contenttypes.admin.GenericInlineModelAdmin`)
+provided by :mod:`~django.contrib.contenttypes.admin`, they implement tabular and
stacked visual layouts for the forms representing the inline objects
respectively just like their non-generic counterparts and behave just like any
other inline. In your ``admin.py`` for this example app::
from django.contrib import admin
- from django.contrib.contenttypes import generic
+ from django.contrib.contenttypes.admin import GenericTabularInline
from myproject.myapp.models import Image, Product
- class ImageInline(generic.GenericTabularInline):
+ class ImageInline(GenericTabularInline):
model = Image
class ProductAdmin(admin.ModelAdmin):
diff --git a/docs/ref/contrib/comments/models.txt b/docs/ref/contrib/comments/models.txt
index cae9c11971..3f9ac740bd 100644
--- a/docs/ref/contrib/comments/models.txt
+++ b/docs/ref/contrib/comments/models.txt
@@ -23,12 +23,12 @@ The built-in comment models
.. attribute:: content_object
- A :class:`~django.contrib.contenttypes.generic.GenericForeignKey`
+ A :class:`~django.contrib.contenttypes.fields.GenericForeignKey`
attribute pointing to the object the comment is attached to. You can use
this to get at the related object (i.e. ``my_comment.content_object``).
Since this field is a
- :class:`~django.contrib.contenttypes.generic.GenericForeignKey`, it's
+ :class:`~django.contrib.contenttypes.fields.GenericForeignKey`, it's
actually syntactic sugar on top of two underlying attributes, described
below.
diff --git a/docs/ref/contrib/contenttypes.txt b/docs/ref/contrib/contenttypes.txt
index 58a309c17d..19c2853722 100644
--- a/docs/ref/contrib/contenttypes.txt
+++ b/docs/ref/contrib/contenttypes.txt
@@ -232,7 +232,7 @@ lookup::
>>> user_type
<ContentType: user>
-.. module:: django.contrib.contenttypes.generic
+.. module:: django.contrib.contenttypes.fields
.. _generic-relations:
@@ -250,14 +250,14 @@ generic (sometimes called "polymorphic") relationships between models.
A simple example is a tagging system, which might look like this::
from django.db import models
+ from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
- from django.contrib.contenttypes import generic
class TaggedItem(models.Model):
tag = models.SlugField()
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
- content_object = generic.GenericForeignKey('content_type', 'object_id')
+ content_object = GenericForeignKey('content_type', 'object_id')
# On Python 3: def __str__(self):
def __unicode__(self):
@@ -274,7 +274,7 @@ model:
.. class:: GenericForeignKey
There are three parts to setting up a
- :class:`~django.contrib.contenttypes.generic.GenericForeignKey`:
+ :class:`~django.contrib.contenttypes.fields.GenericForeignKey`:
1. Give your model a :class:`~django.db.models.ForeignKey`
to :class:`~django.contrib.contenttypes.models.ContentType`. The usual
@@ -286,11 +286,11 @@ model:
for this field is "object_id".
3. Give your model a
- :class:`~django.contrib.contenttypes.generic.GenericForeignKey`, and
+ :class:`~django.contrib.contenttypes.fields.GenericForeignKey`, and
pass it the names of the two fields described above. If these fields
are named "content_type" and "object_id", you can omit this -- those
are the default field names
- :class:`~django.contrib.contenttypes.generic.GenericForeignKey` will
+ :class:`~django.contrib.contenttypes.fields.GenericForeignKey` will
look for.
.. attribute:: GenericForeignKey.for_concrete_model
@@ -301,6 +301,10 @@ model:
is ``True``. This mirrors the ``for_concrete_model`` argument to
:meth:`~django.contrib.contenttypes.models.ContentTypeManager.get_for_model`.
+ .. versionchanged:: 1.7
+
+ This class used to be defined in ``django.contrib.contenttypes.generic``.
+
.. admonition:: Primary key type compatibility
@@ -347,10 +351,10 @@ creating a ``TaggedItem``::
>>> t.content_object
<User: Guido>
-Due to the way :class:`~django.contrib.contenttypes.generic.GenericForeignKey`
+Due to the way :class:`~django.contrib.contenttypes.fields.GenericForeignKey`
is implemented, you cannot use such fields directly with filters (``filter()``
and ``exclude()``, for example) via the database API. Because a
-:class:`~django.contrib.contenttypes.generic.GenericForeignKey` isn't a
+:class:`~django.contrib.contenttypes.fields.GenericForeignKey` isn't a
normal field object, these examples will *not* work::
# This will fail
@@ -358,7 +362,7 @@ normal field object, these examples will *not* work::
# This will also fail
>>> TaggedItem.objects.get(content_object=guido)
-Likewise, :class:`~django.contrib.contenttypes.generic.GenericForeignKey`\s
+Likewise, :class:`~django.contrib.contenttypes.fields.GenericForeignKey`\s
does not appear in :class:`~django.forms.ModelForm`\s.
Reverse generic relations
@@ -366,12 +370,16 @@ Reverse generic relations
.. class:: GenericRelation
+ .. versionchanged:: 1.7
+
+ This class used to be defined in ``django.contrib.contenttypes.generic``.
+
If you know which models you'll be using most often, you can also add
a "reverse" generic relationship to enable an additional API. For example::
class Bookmark(models.Model):
url = models.URLField()
- tags = generic.GenericRelation(TaggedItem)
+ tags = GenericRelation(TaggedItem)
``Bookmark`` instances will each have a ``tags`` attribute, which can
be used to retrieve their associated ``TaggedItems``::
@@ -385,10 +393,10 @@ be used to retrieve their associated ``TaggedItems``::
>>> b.tags.all()
[<TaggedItem: django>, <TaggedItem: python>]
-Just as :class:`~django.contrib.contenttypes.generic.GenericForeignKey`
+Just as :class:`~django.contrib.contenttypes.fields.GenericForeignKey`
accepts the names of the content-type and object-ID fields as
arguments, so too does
-:class:`~django.contrib.contenttypes.generic.GenericRelation`;
+:class:`~django.contrib.contenttypes.fields.GenericRelation`;
if the model which has the generic foreign key is using non-default names
for those fields, you must pass the names of the fields when setting up a
:class:`.GenericRelation` to it. For example, if the ``TaggedItem`` model
@@ -396,9 +404,9 @@ referred to above used fields named ``content_type_fk`` and
``object_primary_key`` to create its generic foreign key, then a
:class:`.GenericRelation` back to it would need to be defined like so::
- tags = generic.GenericRelation(TaggedItem,
- content_type_field='content_type_fk',
- object_id_field='object_primary_key')
+ tags = GenericRelation(TaggedItem,
+ content_type_field='content_type_fk',
+ object_id_field='object_primary_key')
Of course, if you don't add the reverse relationship, you can do the
same types of lookups manually::
@@ -410,29 +418,29 @@ same types of lookups manually::
[<TaggedItem: django>, <TaggedItem: python>]
Note that if the model in a
-:class:`~django.contrib.contenttypes.generic.GenericRelation` uses a
+:class:`~django.contrib.contenttypes.fields.GenericRelation` uses a
non-default value for ``ct_field`` or ``fk_field`` in its
-:class:`~django.contrib.contenttypes.generic.GenericForeignKey` (e.g. the
+:class:`~django.contrib.contenttypes.fields.GenericForeignKey` (e.g. the
:mod:`django.contrib.comments` app uses ``ct_field="object_pk"``),
you'll need to set ``content_type_field`` and/or ``object_id_field`` in
-the :class:`~django.contrib.contenttypes.generic.GenericRelation` to
+the :class:`~django.contrib.contenttypes.fields.GenericRelation` to
match the ``ct_field`` and ``fk_field``, respectively, in the
-:class:`~django.contrib.contenttypes.generic.GenericForeignKey`::
+:class:`~django.contrib.contenttypes.fields.GenericForeignKey`::
- comments = generic.GenericRelation(Comment, object_id_field="object_pk")
+ comments = fields.GenericRelation(Comment, object_id_field="object_pk")
Note also, that if you delete an object that has a
-:class:`~django.contrib.contenttypes.generic.GenericRelation`, any objects
-which have a :class:`~django.contrib.contenttypes.generic.GenericForeignKey`
+:class:`~django.contrib.contenttypes.fields.GenericRelation`, any objects
+which have a :class:`~django.contrib.contenttypes.fields.GenericForeignKey`
pointing at it will be deleted as well. In the example above, this means that
if a ``Bookmark`` object were deleted, any ``TaggedItem`` objects pointing at
it would be deleted at the same time.
Unlike :class:`~django.db.models.ForeignKey`,
-:class:`~django.contrib.contenttypes.generic.GenericForeignKey` does not accept
+:class:`~django.contrib.contenttypes.fields.GenericForeignKey` does not accept
an :attr:`~django.db.models.ForeignKey.on_delete` argument to customize this
behavior; if desired, you can avoid the cascade-deletion simply by not using
-:class:`~django.contrib.contenttypes.generic.GenericRelation`, and alternate
+:class:`~django.contrib.contenttypes.fields.GenericRelation`, and alternate
behavior can be provided via the :data:`~django.db.models.signals.pre_delete`
signal.
@@ -441,7 +449,7 @@ Generic relations and aggregation
:doc:`Django's database aggregation API </topics/db/aggregation>`
doesn't work with a
-:class:`~django.contrib.contenttypes.generic.GenericRelation`. For example, you
+:class:`~django.contrib.contenttypes.fields.GenericRelation`. For example, you
might be tempted to try something like::
Bookmark.objects.aggregate(Count('tags'))
@@ -452,18 +460,55 @@ to the queryset to ensure the correct content type, but the
into account. For now, if you need aggregates on generic relations, you'll
need to calculate them without using the aggregation API.
-Generic relations in forms and admin
-------------------------------------
-The :mod:`django.contrib.contenttypes.generic` module provides:
+.. module:: django.contrib.contenttypes.forms
+
+Generic relation in forms
+-------------------------
-* ``BaseGenericInlineFormSet``
-* :class:`~django.contrib.contenttypes.generic.GenericTabularInline`
- and :class:`~django.contrib.contenttypes.generic.GenericStackedInline`
- (subclasses of
- :class:`~django.contrib.contenttypes.generic.GenericInlineModelAdmin`)
+The :mod:`django.contrib.contenttypes.forms` module provides:
+
+* :class:`BaseGenericInlineFormSet`
* A formset factory, :func:`generic_inlineformset_factory`, for use with
- :class:`GenericForeignKey`
+ :class:`~django.contrib.contenttypes.fields.GenericForeignKey`.
+
+.. class:: BaseGenericInlineFormSet
+
+ .. versionchanged:: 1.7
+
+ This class used to be defined in ``django.contrib.contenttypes.generic``.
+
+.. function:: generic_inlineformset_factory(model, form=ModelForm, formset=BaseGenericInlineFormSet, ct_field="content_type", fk_field="object_id", fields=None, exclude=None, extra=3, can_order=False, can_delete=True, max_num=None, formfield_callback=None, validate_max=False, for_concrete_model=True)
+
+ Returns a ``GenericInlineFormSet`` using
+ :func:`~django.forms.models.modelformset_factory`.
+
+ You must provide ``ct_field`` and ``fk_field`` if they are different from
+ the defaults, ``content_type`` and ``object_id`` respectively. Other
+ parameters are similar to those documented in
+ :func:`~django.forms.models.modelformset_factory` and
+ :func:`~django.forms.models.inlineformset_factory`.
+
+ .. versionadded:: 1.6
+
+ The ``for_concrete_model`` argument corresponds to the
+ :class:`~django.contrib.contenttypes.fields.GenericForeignKey.for_concrete_model`
+ argument on ``GenericForeignKey``.
+
+ .. versionchanged:: 1.7
+
+ This function used to be defined in ``django.contrib.contenttypes.generic``.
+
+
+.. module:: django.contrib.contenttypes.admin
+
+Generic relations in admin
+------------------------------------
+
+The :mod:`django.contrib.contenttypes.admin` module provides
+:class:`~django.contrib.contenttypes.admin.GenericTabularInline` and
+:class:`~django.contrib.contenttypes.admin.GenericStackedInline` (subclasses of
+:class:`~django.contrib.contenttypes.admin.GenericInlineModelAdmin`)
These classes and functions enable the use of generic relations in forms
and the admin. See the :doc:`model formset </topics/forms/modelforms>` and
@@ -472,7 +517,7 @@ information.
.. class:: GenericInlineModelAdmin
- The :class:`~django.contrib.contenttypes.generic.GenericInlineModelAdmin`
+ The :class:`~django.contrib.contenttypes.admin.GenericInlineModelAdmin`
class inherits all properties from an
:class:`~django.contrib.admin.InlineModelAdmin` class. However,
it adds a couple of its own for working with the generic relation:
@@ -488,25 +533,16 @@ information.
The name of the integer field that represents the ID of the related
object. Defaults to ``object_id``.
+ .. versionchanged:: 1.7
+
+ This class used to be defined in ``django.contrib.contenttypes.generic``.
+
.. class:: GenericTabularInline
.. class:: GenericStackedInline
Subclasses of :class:`GenericInlineModelAdmin` with stacked and tabular
layouts, respectively.
-.. function:: generic_inlineformset_factory(model, form=ModelForm, formset=BaseGenericInlineFormSet, ct_field="content_type", fk_field="object_id", fields=None, exclude=None, extra=3, can_order=False, can_delete=True, max_num=None, formfield_callback=None, validate_max=False, for_concrete_model=True)
+ .. versionchanged:: 1.7
- Returns a ``GenericInlineFormSet`` using
- :func:`~django.forms.models.modelformset_factory`.
-
- You must provide ``ct_field`` and ``fk_field`` if they are different from
- the defaults, ``content_type`` and ``object_id`` respectively. Other
- parameters are similar to those documented in
- :func:`~django.forms.models.modelformset_factory` and
- :func:`~django.forms.models.inlineformset_factory`.
-
- .. versionadded:: 1.6
-
- The ``for_concrete_model`` argument corresponds to the
- :class:`~django.contrib.contenttypes.generic.GenericForeignKey.for_concrete_model`
- argument on ``GenericForeignKey``.
+ These classes used to be defined in ``django.contrib.contenttypes.generic``.
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index 5e310e7ac3..c063d38aa6 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -798,8 +798,8 @@ relationship, and does the 'joining' in Python. This allows it to prefetch
many-to-many and many-to-one objects, which cannot be done using
``select_related``, in addition to the foreign key and one-to-one relationships
that are supported by ``select_related``. It also supports prefetching of
-:class:`~django.contrib.contenttypes.generic.GenericRelation` and
-:class:`~django.contrib.contenttypes.generic.GenericForeignKey`.
+:class:`~django.contrib.contenttypes.fields.GenericRelation` and
+:class:`~django.contrib.contenttypes.fields.GenericForeignKey`.
For example, suppose you have these models::
diff --git a/docs/releases/1.4-alpha-1.txt b/docs/releases/1.4-alpha-1.txt
index d47f624f5b..ebd0084469 100644
--- a/docs/releases/1.4-alpha-1.txt
+++ b/docs/releases/1.4-alpha-1.txt
@@ -92,8 +92,7 @@ different strategy and broader scope,
``QuerySet`` that will prefetch each of the specified related lookups in a
single batch as soon as the query begins to be evaluated. Unlike
``select_related``, it does the joins in Python, not in the database, and
-supports many-to-many relationships,
-:class:`~django.contrib.contenttypes.generic.GenericForeignKey` and more. This
+supports many-to-many relationships, ``GenericForeignKey`` and more. This
allows you to fix a very common performance problem in which your code ends up
doing O(n) database queries (or worse) if objects on your primary ``QuerySet``
each have many related objects that you also need.
diff --git a/docs/releases/1.4-beta-1.txt b/docs/releases/1.4-beta-1.txt
index d670036463..674aa0e944 100644
--- a/docs/releases/1.4-beta-1.txt
+++ b/docs/releases/1.4-beta-1.txt
@@ -108,8 +108,7 @@ different strategy and broader scope,
``QuerySet`` that will prefetch each of the specified related lookups in a
single batch as soon as the query begins to be evaluated. Unlike
``select_related``, it does the joins in Python, not in the database, and
-supports many-to-many relationships,
-:class:`~django.contrib.contenttypes.generic.GenericForeignKey` and more. This
+supports many-to-many relationships, ``GenericForeignKey`` and more. This
allows you to fix a very common performance problem in which your code ends up
doing O(n) database queries (or worse) if objects on your primary ``QuerySet``
each have many related objects that you also need.
diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt
index f8c23728b9..e59917478a 100644
--- a/docs/releases/1.4.txt
+++ b/docs/releases/1.4.txt
@@ -257,8 +257,7 @@ different strategy and broader scope,
``QuerySet`` that will prefetch each of the specified related lookups in a
single batch as soon as the query begins to be evaluated. Unlike
``select_related``, it does the joins in Python, not in the database, and
-supports many-to-many relationships,
-:class:`~django.contrib.contenttypes.generic.GenericForeignKey` and more. This
+supports many-to-many relationships, ``GenericForeignKey`` and more. This
allows you to fix a very common performance problem in which your code ends up
doing O(n) database queries (or worse) if objects on your primary ``QuerySet``
each have many related objects that you also need to fetch.
diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt
index bbdd81a768..8407f4f097 100644
--- a/docs/releases/1.6.txt
+++ b/docs/releases/1.6.txt
@@ -302,11 +302,9 @@ Minor features
:class:`~django.views.generic.base.RedirectView` now support HTTP ``PATCH``
method.
-* :class:`GenericForeignKey <django.contrib.contenttypes.generic.GenericForeignKey>`
- now takes an optional
- :attr:`~django.contrib.contenttypes.generic.GenericForeignKey.for_concrete_model`
- argument, which when set to ``False`` allows the field to reference proxy
- models. The default is ``True`` to retain the old behavior.
+* ``GenericForeignKey`` now takes an optional ``for_concrete_model`` argument,
+ which when set to ``False`` allows the field to reference proxy models. The
+ default is ``True`` to retain the old behavior.
* The :class:`~django.middleware.locale.LocaleMiddleware` now stores the active
language in session if it is not present there. This prevents loss of
diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt
index e56939f3ce..305b34fe55 100644
--- a/docs/releases/1.7.txt
+++ b/docs/releases/1.7.txt
@@ -1030,6 +1030,25 @@ API, it will go through a regular deprecation path. This attribute was mostly
used by methods that bypassed ``ModelAdmin.get_fieldsets()`` but this was
considered a bug and has been addressed.
+Reorganization of ``django.contrib.contenttypes``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Since ``django.contrib.contenttypes.generic`` defined both admin and model
+related objects an import of this module could trigger unexpected side effects.
+As a consequence, its contents were split into :mod:`~django.contrib.contenttypes`
+submodules and the ``django.contrib.contenttypes.generic`` module is deprecated:
+
+* :class:`~django.contrib.contenttypes.fields.GenericForeignKey` and
+ :class:`~django.contrib.contenttypes.fields.GenericRelation` now live in
+ :mod:`~django.contrib.contenttypes.fields`.
+* :class:`~django.contrib.contenttypes.forms.BaseGenericInlineFormSet` and
+ :func:`~django.contrib.contenttypes.forms.generic_inlineformset_factory` now
+ live in :mod:`~django.contrib.contenttypes.forms`.
+* :class:`~django.contrib.contenttypes.admin.GenericInlineModelAdmin`,
+ :class:`~django.contrib.contenttypes.admin.GenericStackedInline` and
+ :class:`~django.contrib.contenttypes.admin.GenericTabularInline` now live in
+ :mod:`~django.contrib.contenttypes.admin`.
+
``syncdb``
~~~~~~~~~~