summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Petrucha <michal.petrucha@koniiiik.org>2016-04-19 22:34:08 +0200
committerTim Graham <timograham@gmail.com>2016-05-03 09:06:26 -0400
commit8a47ba679d2da0dee74671a53ba0cd918b433e34 (patch)
tree651eb70e38c6ba7e688b0cfdd06715a4727a318e
parent8a55982e7086ebd73458f52516732d9f25dd002b (diff)
Refs #16508 -- Made Model.__init__() aware of virtual fields.
It's no longer necessary for GenericForeignKey (and any other virtual fields) to intercept the field's values using the pre_init signal.
-rw-r--r--django/contrib/contenttypes/fields.py21
-rw-r--r--django/db/models/base.py7
-rw-r--r--docs/releases/1.10.txt3
3 files changed, 9 insertions, 22 deletions
diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py
index fb62f0395b..e4bc292642 100644
--- a/django/contrib/contenttypes/fields.py
+++ b/django/contrib/contenttypes/fields.py
@@ -6,7 +6,7 @@ from django.contrib.contenttypes.models import ContentType
from django.core import checks
from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist
from django.db import DEFAULT_DB_ALIAS, models, router, transaction
-from django.db.models import DO_NOTHING, signals
+from django.db.models import DO_NOTHING
from django.db.models.base import ModelBase, make_foreign_order_accessors
from django.db.models.fields.related import (
ForeignObject, ForeignObjectRel, ReverseManyToOneDescriptor,
@@ -54,11 +54,6 @@ class GenericForeignKey(object):
self.model = cls
self.cache_attr = "_%s_cache" % name
cls._meta.add_field(self, private=True)
-
- # Only run pre-initialization field assignment on non-abstract models
- if not cls._meta.abstract:
- signals.pre_init.connect(self.instance_pre_init, sender=cls)
-
setattr(cls, name, self)
def get_filter_kwargs_for_object(self, obj):
@@ -162,20 +157,6 @@ class GenericForeignKey(object):
else:
return []
- def instance_pre_init(self, signal, sender, args, kwargs, **_kwargs):
- """
- Handle initializing an object with the generic FK instead of
- content_type and object_id fields.
- """
- if self.name in kwargs:
- value = kwargs.pop(self.name)
- if value is not None:
- kwargs[self.ct_field] = self.get_content_type(obj=value)
- kwargs[self.fk_field] = value._get_pk_val()
- else:
- kwargs[self.ct_field] = None
- kwargs[self.fk_field] = None
-
def get_content_type(self, obj=None, id=None, using=None):
if obj is not None:
return ContentType.objects.db_manager(obj._state.db).get_for_model(
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 94031d76a9..2a6fa081a4 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -452,11 +452,14 @@ class Model(six.with_metaclass(ModelBase)):
if kwargs:
for prop in list(kwargs):
try:
- if isinstance(getattr(self.__class__, prop), property):
+ # Any remaining kwargs must correspond to properties or
+ # virtual fields.
+ if (isinstance(getattr(self.__class__, prop), property) or
+ self._meta.get_field(prop)):
if kwargs[prop] is not DEFERRED:
setattr(self, prop, kwargs[prop])
del kwargs[prop]
- except AttributeError:
+ except (AttributeError, FieldDoesNotExist):
pass
if kwargs:
raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt
index 3eac9bb311..826752996b 100644
--- a/docs/releases/1.10.txt
+++ b/docs/releases/1.10.txt
@@ -400,6 +400,9 @@ Models
* A proxy model may now inherit multiple proxy models that share a common
non-abstract parent class.
+* ``Model.__init__()`` now sets values of virtual fields from its keyword
+ arguments.
+
Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~