def _get_remote_field_name(field):
reverse_field = True if isinstance(field, (
models.ManyToManyRel, models.ManyToOneRel, models.OneToOneRel, GenericRelation)) else False
return str('{model}.{field}'.format(
model=get_model_string(field.model),
field=(field.related_name or '%s_set' % field.name
if not isinstance(field, (models.OneToOneRel, GenericRelation)) else field.name)) if reverse_field
else field.remote_field.field if not isinstance(field, GenericForeignKey)
else str(field)).lower()
python类GenericForeignKey()的实例源码
def get_cardinality_for_field(field):
"""
Returns the cardinality for ``field``.
"""
cardinalities = {
models.ForeignKey: ZeroOrOne,
models.ManyToOneRel: ZeroOrMore,
models.OneToOneField: ZeroOrOne,
models.OneToOneRel: ZeroOrOne,
models.ManyToManyField: ZeroOrMore,
models.ManyToManyRel: ZeroOrMore,
GenericForeignKey: ZeroOrOne,
GenericRelation: ZeroOrMore
}
return cardinalities[field.__class__]
def get_forward_relation_fields(cls):
return [
field for field in cls.Meta.model._meta.get_fields()
if field.is_relation and (
not field.auto_created or field.concrete
or field.one_to_one
or (field.many_to_one and field.related_model)
or isinstance(field, GenericForeignKey)
)
]
def get_related_node_property_for_field(cls, field, meta_node=False):
"""
Get the relationship definition for the related node based on field.
:param field: Field to inspect
:param meta_node: If True, return the meta node for the related model,
else return the model node.
:returns: A ``RelationshipDefinition`` instance.
"""
from chemtrails.neoutils import (
__meta_cache__, __node_cache__,
get_node_class_for_model, get_meta_node_class_for_model
)
reverse_field = True if isinstance(field, (
models.ManyToManyRel, models.ManyToOneRel, models.OneToOneRel, GenericRelation)) else False
class DynamicRelation(StructuredRel):
type = StringProperty(default=field.__class__.__name__)
is_meta = BooleanProperty(default=meta_node)
remote_field = StringProperty(default=cls._get_remote_field_name(field))
target_field = StringProperty(default=str(getattr(field, 'target_field', '')).lower()) # NOTE: Workaround for #27
prop = cls.get_property_class_for_field(field.__class__)
relationship_type = cls.get_relationship_type(field)
related_model = field.model if isinstance(field, GenericForeignKey) else field.related_model
if meta_node:
klass = (__meta_cache__[related_model]
if related_model in __meta_cache__
else get_meta_node_class_for_model(related_model))
return (prop(cls_name=klass, rel_type=relationship_type, model=DynamicRelation)
# FIXME: Support cardinality for MetaNodes
if not klass._is_ignored else None)
else:
klass = (__node_cache__[related_model]
if reverse_field and related_model in __node_cache__
else get_node_class_for_model(related_model))
return (prop(cls_name=klass, rel_type=relationship_type, model=DynamicRelation,
cardinality=cls.get_cardinality_for_field(field)) if not klass._is_ignored else None)
def test_content_object(self):
field = ServeLog._meta.get_field('content_object')
self.assertEqual(field.__class__, GenericForeignKey)
self.assertEqual(field.ct_field, 'content_type')
self.assertEqual(field.fk_field, 'object_id')
def test_form_field(self):
"""
The model should have a form field
"""
field = OmniField.form
self.assertIsInstance(field, GenericForeignKey)
def test_form(self):
"""
The model should have a 'form' field
"""
field = OmniFormHandler.form
self.assertIsInstance(field, GenericForeignKey)
def get_model_fields(self):
"""
Method to get all model fields for the content type
associated with the forms specified content type
:return: List of model field instances
"""
def is_valid_field(field):
if isinstance(field, (models.AutoField, ForeignObjectRel, GenericRelation, GenericForeignKey)):
return False
else:
return True
return list(filter(is_valid_field, self.content_type.model_class()._meta.get_fields()))
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def restore_object(self, attrs, instance=None):
"""
Restore the model instance.
"""
m2m_data = {}
related_data = {}
nested_forward_relations = {}
# noinspection PyProtectedMember
meta = self.opts.model._meta
# Reverse fk or one-to-one relations
for (obj, model) in meta.get_all_related_objects_with_model():
field_name = obj.get_accessor_name()
if field_name in attrs:
related_data[field_name] = attrs.pop(field_name)
# Reverse m2m relations
for (obj, model) in meta.get_all_related_m2m_objects_with_model():
field_name = obj.get_accessor_name()
if field_name in attrs:
m2m_data[field_name] = attrs.pop(field_name)
# Forward m2m relations
if issubclass(meta.many_to_many.__class__, tuple):
temp_m2m = list(meta.many_to_many)
else:
temp_m2m = meta.many_to_many
for field in temp_m2m + meta.virtual_fields:
if isinstance(field, GenericForeignKey):
continue
if field.name in attrs:
m2m_data[field.name] = attrs.pop(field.name)
# Nested forward relations - These need to be marked so we can save
# them before saving the parent model instance.
for field_name in attrs.keys():
if isinstance(self.fields.get(field_name, None), Serializer):
nested_forward_relations[field_name] = attrs[field_name]
# Create an empty instance of the model
if instance is None:
instance = self.opts.model()
for key, val in attrs.items():
try:
setattr(instance, key, val)
except ValueError:
self._errors[key] = [self.error_messages['required']]
# Any relations that cannot be set until we've
# saved the model get hidden away on these
# private attributes, so we can deal with them
# at the point of save.
instance._related_data = related_data
instance._m2m_data = m2m_data
instance._nested_forward_relations = nested_forward_relations
return instance
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def __init__(self, instance=None, bind=False, *args, **kwargs):
self._instance = instance
self.__recursion_depth__ = 0
defaults = {key: getattr(self._instance, key, kwargs.get(key, None))
for key, _ in self.__all_properties__}
kwargs.update(defaults)
super(ModelNodeMixinBase, self).__init__(self, *args, **kwargs)
# Never try to bind ignore nodes
if bind and self._is_ignored:
bind = False
# Query the database for an existing node and set the id if found.
# This will make this a "bound" node.
if bind and not hasattr(self, 'id'):
required = {key: prop for key, prop in self.defined_properties(aliases=False, rels=False).items()
if prop.required or prop.unique_index}
if all(getattr(self, attr) for attr in required.keys()):
node_id = self._get_id_from_database(self.deflate(self.__properties__))
if node_id:
self.id = node_id
if not self._instance and self.pk:
self._instance = self.get_object(self.pk)
if self._instance:
# For GenericForeignKey fields, we have no way of knowing what kind of
# object it is related to during class creation, thus the relationship
# definition is set to refer itself.
# When initializing we have access to the underlying django object instance and
# can inspect it, so we need to switch out the relationship definition
# node class in order to connect to the correct node.
from chemtrails.neoutils import get_node_class_for_model
generic_fks = filter(lambda f: isinstance(f, GenericForeignKey),
self.get_forward_relation_fields())
for field in generic_fks:
relationship = self.defined_properties(aliases=False, properties=False).get(field.name, None)
if isinstance(getattr(self._instance, field.name, None), models.Model) and relationship:
node_class = get_node_class_for_model(getattr(self._instance, field.name))
model = relationship.definition['model']
model.target_field.default = str(node_class._pk_field).lower()
# defensively set the definition dictionary to a dict like class
# which will protect the safeguarded keys against being copied over
# by neomodel
relationship.definition = DefinitionDict(relationship.definition)
relationship.definition._safeguard('node_class', node_class)
relationship.definition._safeguard('model', model)
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]
def _check_relation(self, obj, parent_model):
# There's no FK, but we do need to confirm that the ct_field and ct_fk_field are valid,
# and that they are part of a GenericForeignKey.
gfks = [
f for f in obj.model._meta.private_fields
if isinstance(f, GenericForeignKey)
]
if len(gfks) == 0:
return [
checks.Error(
"'%s.%s' has no GenericForeignKey." % (
obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E301'
)
]
else:
# Check that the ct_field and ct_fk_fields exist
try:
obj.model._meta.get_field(obj.ct_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E302'
)
]
try:
obj.model._meta.get_field(obj.ct_fk_field)
except FieldDoesNotExist:
return [
checks.Error(
"'ct_fk_field' references '%s', which is not a field on '%s.%s'." % (
obj.ct_fk_field, obj.model._meta.app_label, obj.model._meta.object_name
),
obj=obj.__class__,
id='admin.E303'
)
]
# There's one or more GenericForeignKeys; make sure that one of them
# uses the right ct_field and ct_fk_field.
for gfk in gfks:
if gfk.ct_field == obj.ct_field and gfk.fk_field == obj.ct_fk_field:
return []
return [
checks.Error(
"'%s.%s' has no GenericForeignKey using content type field '%s' and object ID field '%s'." % (
obj.model._meta.app_label, obj.model._meta.object_name, obj.ct_field, obj.ct_fk_field
),
obj=obj.__class__,
id='admin.E304'
)
]