Ticket #14820: 14820-textfield-generic-relations-r15449.diff
File 14820-textfield-generic-relations-r15449.diff, 7.7 KB (added by , 14 years ago) |
---|
-
docs/ref/contrib/contenttypes.txt
60 60 .. class:: models.ContentType 61 61 62 62 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: 64 65 65 66 .. attribute:: models.ContentType.app_label 66 67 67 68 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". 72 73 73 74 .. attribute:: models.ContentType.model 74 75 … … 105 106 106 107 Each :class:`~django.contrib.contenttypes.models.ContentType` instance has 107 108 methods that allow you to get from a 108 :class:`~django.contrib.contenttypes.models.ContentType` instance to the model109 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: 110 111 111 112 .. method:: models.ContentType.get_object_for_this_type(**kwargs) 112 113 … … 139 140 140 141 Together, 141 142 :meth:`~django.contrib.contenttypes.models.ContentType.get_object_for_this_type` 142 and :meth:`~django.contrib.contenttypes.models.ContentType.model_class` 143 enabletwo extremely important use cases:143 and :meth:`~django.contrib.contenttypes.models.ContentType.model_class` enable 144 two extremely important use cases: 144 145 145 146 1. Using these methods, you can write high-level generic code that 146 performs queries on any installed model -- instead of importing and using147 a single specific model class, you can pass an ``app_label`` and148 ``model`` into a :class:`~django.contrib.contenttypes.models.ContentType`149 lookup at runtime, and then work with the model class or retrieve objects150 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. 151 152 152 153 2. You can relate another model to 153 154 :class:`~django.contrib.contenttypes.models.ContentType` as a way of … … 187 188 :class:`~django.contrib.contenttypes.models.ContentType` instance 188 189 representing that model. 189 190 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:: 191 The :meth:`~models.ContentTypeManager.get_for_model()` method is especially 192 useful when you know you need to work with a 193 :class:`ContentType <django.contrib.contenttypes.models.ContentType>` but don't 194 want to go to the trouble of obtaining the model's metadata to perform a manual 195 lookup:: 193 196 194 197 >>> from django.contrib.auth.models import User 195 198 >>> user_type = ContentType.objects.get_for_model(User) … … 237 240 1. Give your model a :class:`~django.db.models.fields.related.ForeignKey` 238 241 to :class:`~django.contrib.contenttypes.models.ContentType`. 239 242 240 2. Give your model a field that can store a primary-key valuefrom the241 models you'll be relating to. (For most models, this means an242 :class:`~django.db.models.fields. IntegerField` or243 :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.PositiveIntegerField`. The usual 246 name for this field is "object_id". 244 247 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 250 249 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 251 278 3. Give your model a 252 279 :class:`~django.contrib.contenttypes.generic.GenericForeignKey`, and 253 280 pass it the names of the two fields described above. If these fields … … 311 338 ``object_primary_key`` to create its generic foreign key, then a 312 339 ``GenericRelation`` back to it would need to be defined like so:: 313 340 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') 315 344 316 345 Of course, if you don't add the reverse relationship, you can do the 317 346 same types of lookups manually:: … … 362 391 Bookmark.objects.aggregate(Count('tags')) 363 392 364 393 This 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. 394 to the queryset to ensure the correct content type, but the ``aggregate`` 395 method doesn't take them into account. For now, if you need aggregates on 396 generic relations, you'll need to calculate them without using the aggregation 397 API. 368 398 369 399 Generic relations in forms and admin 370 400 ------------------------------------