diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py
index 40c3336..4bafe81 100644
a
|
b
|
Classes allowing "generic" relations through ContentType and object-id fields.
|
3 | 3 | """ |
4 | 4 | |
5 | 5 | from django.core.exceptions import ObjectDoesNotExist |
6 | | from django.db import connection |
7 | 6 | from django.db.models import signals |
8 | 7 | from django.db import models, router |
9 | 8 | from django.db.models.fields.related import RelatedField, Field, ManyToManyRel |
… |
… |
class ReverseGenericRelatedObjectsDescriptor(object):
|
183 | 182 | if instance is None: |
184 | 183 | return self |
185 | 184 | |
186 | | # This import is done here to avoid circular import importing this module |
187 | | from django.contrib.contenttypes.models import ContentType |
188 | | |
189 | 185 | # Dynamically create a class that subclasses the related model's |
190 | 186 | # default manager. |
191 | 187 | rel_model = self.field.rel.to |
192 | 188 | superclass = rel_model._default_manager.__class__ |
193 | 189 | RelatedManager = create_generic_related_manager(superclass) |
194 | | |
195 | | qn = connection.ops.quote_name |
| 190 | |
| 191 | # Imported here to avoid circular import |
| 192 | from django.contrib.contenttypes.models import ContentType |
196 | 193 | |
197 | 194 | manager = RelatedManager( |
198 | 195 | model = rel_model, |
199 | 196 | instance = instance, |
200 | 197 | symmetrical = (self.field.rel.symmetrical and instance.__class__ == rel_model), |
201 | | join_table = qn(self.field.m2m_db_table()), |
202 | | source_col_name = qn(self.field.m2m_column_name()), |
203 | | target_col_name = qn(self.field.m2m_reverse_name()), |
204 | | content_type = ContentType.objects.db_manager(instance._state.db).get_for_model(instance), |
| 198 | content_type = ContentType.objects.get_for_model(instance), |
205 | 199 | content_type_field_name = self.field.content_type_field_name, |
206 | 200 | object_id_field_name = self.field.object_id_field_name |
207 | 201 | ) |
… |
… |
def create_generic_related_manager(superclass):
|
224 | 218 | """ |
225 | 219 | |
226 | 220 | class GenericRelatedObjectManager(superclass): |
227 | | def __init__(self, model=None, core_filters=None, instance=None, symmetrical=None, |
228 | | join_table=None, source_col_name=None, target_col_name=None, content_type=None, |
229 | | content_type_field_name=None, object_id_field_name=None): |
230 | | |
| 221 | def __init__(self, model=None, core_filters=None, instance=None, |
| 222 | symmetrical=None, content_type=None, content_type_field_name=None, |
| 223 | object_id_field_name=None): |
231 | 224 | super(GenericRelatedObjectManager, self).__init__() |
232 | 225 | self.core_filters = core_filters or {} |
233 | 226 | self.model = model |
234 | | self.content_type = content_type |
235 | 227 | self.symmetrical = symmetrical |
236 | 228 | self.instance = instance |
237 | | self.join_table = join_table |
238 | | self.join_table = model._meta.db_table |
239 | | self.source_col_name = source_col_name |
240 | | self.target_col_name = target_col_name |
| 229 | self.content_type = content_type |
241 | 230 | self.content_type_field_name = content_type_field_name |
242 | 231 | self.object_id_field_name = object_id_field_name |
243 | 232 | self.pk_val = self.instance._get_pk_val() |
244 | | |
| 233 | |
245 | 234 | def get_query_set(self): |
246 | 235 | db = self._db or router.db_for_read(self.model, instance=self.instance) |
247 | 236 | query = { |
248 | | '%s__pk' % self.content_type_field_name : self.content_type.id, |
| 237 | '%s__pk' % self.content_type_field_name : self.content_type.pk, |
249 | 238 | '%s__exact' % self.object_id_field_name : self.pk_val, |
250 | 239 | } |
251 | 240 | return superclass.get_query_set(self).using(db).filter(**query) |
… |
… |
def create_generic_related_manager(superclass):
|
253 | 242 | def add(self, *objs): |
254 | 243 | for obj in objs: |
255 | 244 | if not isinstance(obj, self.model): |
256 | | raise TypeError("'%s' instance expected" % self.model._meta.object_name) |
| 245 | raise TypeError("'%s' instance expected" % |
| 246 | self.model._meta.object_name) |
257 | 247 | setattr(obj, self.content_type_field_name, self.content_type) |
258 | 248 | setattr(obj, self.object_id_field_name, self.pk_val) |
259 | 249 | obj.save() |
… |
… |
def create_generic_related_manager(superclass):
|
272 | 262 | clear.alters_data = True |
273 | 263 | |
274 | 264 | def create(self, **kwargs): |
| 265 | db = router.db_for_write(self.model, instance=self.instance) |
275 | 266 | kwargs[self.content_type_field_name] = self.content_type |
276 | 267 | kwargs[self.object_id_field_name] = self.pk_val |
277 | | db = router.db_for_write(self.model, instance=self.instance) |
278 | 268 | return super(GenericRelatedObjectManager, self).using(db).create(**kwargs) |
279 | 269 | create.alters_data = True |
280 | 270 | |