def _check_raw_id_fields_item(self, obj, model, field_name, label):
""" Check an item of `raw_id_fields`, i.e. check that field named
`field_name` exists in model `model` and is a ForeignKey or a
ManyToManyField. """
try:
field = model._meta.get_field(field_name)
except FieldDoesNotExist:
return refer_to_missing_field(field=field_name, option=label,
model=model, obj=obj, id='admin.E002')
else:
if not isinstance(field, (models.ForeignKey, models.ManyToManyField)):
return must_be('a ForeignKey or ManyToManyField',
option=label, obj=obj, id='admin.E003')
else:
return []
python类FieldDoesNotExist()的实例源码
def get_header_name(self, model, field_name):
""" Override if a custom value or behaviour is required for specific fields. """
if '__' not in field_name:
try:
field = model._meta.get_field(field_name)
except FieldDoesNotExist as e:
if not hasattr(model, field_name):
raise e
# field_name is a property.
return field_name.replace('_', ' ').title()
return force_text(field.verbose_name).title()
else:
related_field_names = field_name.split('__')
field = model._meta.get_field(related_field_names[0])
assert field.is_relation
return self.get_header_name(field.related_model, '__'.join(related_field_names[1:]))
def handle(self, *args, **options):
""" Try to set the attribute on the job.
Invalid job ID warns, any other error raises """
try:
qs = AnalysisJob.objects.filter(pk=options['job_id'])
# Force qs evaluation to catch invalid job_id errors
qs.exists()
except (ValueError, AnalysisJob.DoesNotExist):
print ("WARNING: Tried to update attribute '{attr}' "
"for invalid job {job_id}.".format(**options))
else:
try:
qs.update(**{options['attr']: options['value']})
except (FieldDoesNotExist, ValueError, TypeError):
print ("Error trying to update attribute '{attr}' to '{value}' "
"for {job_id}.".format(**options))
raise
else:
self.stdout.write("{job_id}: Set '{attr}' to '{value}'".format(**options))
def _check_radio_fields_key(self, obj, model, field_name, label):
""" Check that a key of `radio_fields` dictionary is name of existing
field and that the field is a ForeignKey or has `choices` defined. """
try:
field = model._meta.get_field(field_name)
except FieldDoesNotExist:
return refer_to_missing_field(field=field_name, option=label,
model=model, obj=obj, id='admin.E022')
else:
if not (isinstance(field, models.ForeignKey) or field.choices):
return [
checks.Error(
"The value of '%s' refers to '%s', which is not an "
"instance of ForeignKey, and does not have a 'choices' definition." % (
label, field_name
),
hint=None,
obj=obj.__class__,
id='admin.E023',
)
]
else:
return []
def _check_date_hierarchy(self, obj):
""" Check that date_hierarchy refers to DateField or DateTimeField. """
if obj.date_hierarchy is None:
return []
else:
try:
field = obj.model._meta.get_field(obj.date_hierarchy)
except FieldDoesNotExist:
return refer_to_missing_field(option='date_hierarchy',
field=obj.date_hierarchy,
model=obj.model, obj=obj, id='admin.E127')
else:
if not isinstance(field, (models.DateField, models.DateTimeField)):
return must_be('a DateField or DateTimeField', option='date_hierarchy',
obj=obj, id='admin.E128')
else:
return []
def _check_field_name(self):
field_name = self._get_field_name()
try:
field = self.model._meta.get_field(field_name)
except FieldDoesNotExist:
return [
checks.Error(
"CurrentSiteManager could not find a field named '%s'." % field_name,
obj=self,
id='sites.E001',
)
]
if not field.many_to_many and not isinstance(field, (models.ForeignKey)):
return [
checks.Error(
"CurrentSiteManager cannot use '%s.%s' as it is not a foreign key or a many-to-many field." % (
self.model._meta.object_name, field_name
),
obj=self,
id='sites.E002',
)
]
return []
def _check_radio_fields_key(self, obj, model, field_name, label):
""" Check that a key of `radio_fields` dictionary is name of existing
field and that the field is a ForeignKey or has `choices` defined. """
try:
field = model._meta.get_field(field_name)
except FieldDoesNotExist:
return refer_to_missing_field(field=field_name, option=label,
model=model, obj=obj, id='admin.E022')
else:
if not (isinstance(field, models.ForeignKey) or field.choices):
return [
checks.Error(
"The value of '%s' refers to '%s', which is not an "
"instance of ForeignKey, and does not have a 'choices' definition." % (
label, field_name
),
obj=obj.__class__,
id='admin.E023',
)
]
else:
return []
def _check_prepopulated_fields_key(self, obj, model, field_name, label):
""" Check a key of `prepopulated_fields` dictionary, i.e. check that it
is a name of existing field and the field is one of the allowed types.
"""
try:
field = model._meta.get_field(field_name)
except FieldDoesNotExist:
return refer_to_missing_field(field=field_name, option=label,
model=model, obj=obj, id='admin.E027')
else:
if isinstance(field, (models.DateTimeField, models.ForeignKey, models.ManyToManyField)):
return [
checks.Error(
"The value of '%s' refers to '%s', which must not be a DateTimeField, "
"a ForeignKey, or a ManyToManyField." % (label, field_name),
obj=obj.__class__,
id='admin.E028',
)
]
else:
return []
def _check_readonly_fields_item(self, obj, model, field_name, label):
if callable(field_name):
return []
elif hasattr(obj, field_name):
return []
elif hasattr(model, field_name):
return []
else:
try:
model._meta.get_field(field_name)
except FieldDoesNotExist:
return [
checks.Error(
"The value of '%s' is not a callable, an attribute of '%s', or an attribute of '%s.%s'." % (
label, obj.__class__.__name__, model._meta.app_label, model._meta.object_name
),
obj=obj.__class__,
id='admin.E035',
)
]
else:
return []
def _check_date_hierarchy(self, obj):
""" Check that date_hierarchy refers to DateField or DateTimeField. """
if obj.date_hierarchy is None:
return []
else:
try:
field = obj.model._meta.get_field(obj.date_hierarchy)
except FieldDoesNotExist:
return refer_to_missing_field(
option='date_hierarchy', field=obj.date_hierarchy,
model=obj.model, obj=obj, id='admin.E127',
)
else:
if not isinstance(field, (models.DateField, models.DateTimeField)):
return must_be('a DateField or DateTimeField', option='date_hierarchy', obj=obj, id='admin.E128')
else:
return []
def _get_field(self, lookup):
'''
Return the Django model field for a lookup plus the remainder of the lookup,
which should be the lookup type.
'''
field = None
lookup_type = None
bits = lookup.split(LOOKUP_SEP)
model = self.model
for i, bit in enumerate(bits):
try:
field = model._meta.get_field(bit)
except FieldDoesNotExist:
lookup_type = LOOKUP_SEP.join(bits[i:])
break
if hasattr(field, 'remote_field'):
rel = getattr(field, 'remote_field', None)
model = getattr(rel, 'model', model)
return field, lookup_type
def _check_field_name(self):
field_name = self._get_field_name()
try:
field = self.model._meta.get_field(field_name)
except FieldDoesNotExist:
return [
checks.Error(
"CurrentSiteManager could not find a field named '%s'." % field_name,
obj=self,
id='sites.E001',
)
]
if not field.many_to_many and not isinstance(field, (models.ForeignKey)):
return [
checks.Error(
"CurrentSiteManager cannot use '%s.%s' as it is not a foreign key or a many-to-many field." % (
self.model._meta.object_name, field_name
),
obj=self,
id='sites.E002',
)
]
return []
def _get_non_gfk_field(opts, name):
"""
For historical reasons, the admin app relies on GenericForeignKeys as being
"not found" by get_field(). This could likely be cleaned up.
Reverse relations should also be excluded as these aren't attributes of the
model (rather something like `foo_set`).
"""
field = opts.get_field(name)
if (field.is_relation and
# Generic foreign keys OR reverse relations
((field.many_to_one and not field.related_model) or field.one_to_many)):
raise FieldDoesNotExist()
# Avoid coercing <FK>_id fields to FK
if field.is_relation and not field.many_to_many and hasattr(field, 'attname') and field.attname == name:
raise FieldIsAForeignKeyColumnName()
return field
def _check_radio_fields_key(self, obj, model, field_name, label):
""" Check that a key of `radio_fields` dictionary is name of existing
field and that the field is a ForeignKey or has `choices` defined. """
try:
field = model._meta.get_field(field_name)
except FieldDoesNotExist:
return refer_to_missing_field(field=field_name, option=label,
model=model, obj=obj, id='admin.E022')
else:
if not (isinstance(field, models.ForeignKey) or field.choices):
return [
checks.Error(
"The value of '%s' refers to '%s', which is not an "
"instance of ForeignKey, and does not have a 'choices' definition." % (
label, field_name
),
obj=obj.__class__,
id='admin.E023',
)
]
else:
return []
def _check_prepopulated_fields_key(self, obj, model, field_name, label):
""" Check a key of `prepopulated_fields` dictionary, i.e. check that it
is a name of existing field and the field is one of the allowed types.
"""
try:
field = model._meta.get_field(field_name)
except FieldDoesNotExist:
return refer_to_missing_field(field=field_name, option=label,
model=model, obj=obj, id='admin.E027')
else:
if isinstance(field, (models.DateTimeField, models.ForeignKey, models.ManyToManyField)):
return [
checks.Error(
"The value of '%s' refers to '%s', which must not be a DateTimeField, "
"a ForeignKey, a OneToOneField, or a ManyToManyField." % (label, field_name),
obj=obj.__class__,
id='admin.E028',
)
]
else:
return []
def _check_readonly_fields_item(self, obj, model, field_name, label):
if callable(field_name):
return []
elif hasattr(obj, field_name):
return []
elif hasattr(model, field_name):
return []
else:
try:
model._meta.get_field(field_name)
except FieldDoesNotExist:
return [
checks.Error(
"The value of '%s' is not a callable, an attribute of '%s', or an attribute of '%s.%s'." % (
label, obj.__class__.__name__, model._meta.app_label, model._meta.object_name
),
obj=obj.__class__,
id='admin.E035',
)
]
else:
return []
def _check_date_hierarchy(self, obj):
""" Check that date_hierarchy refers to DateField or DateTimeField. """
if obj.date_hierarchy is None:
return []
else:
try:
field = get_fields_from_path(obj.model, obj.date_hierarchy)[-1]
except (NotRelationField, FieldDoesNotExist):
return [
checks.Error(
"The value of 'date_hierarchy' refers to '%s', which "
"does not refer to a Field." % obj.date_hierarchy,
obj=obj.__class__,
id='admin.E127',
)
]
else:
if not isinstance(field, (models.DateField, models.DateTimeField)):
return must_be('a DateField or DateTimeField', option='date_hierarchy', obj=obj, id='admin.E128')
else:
return []
def _check_field_name(self):
field_name = self._get_field_name()
try:
field = self.model._meta.get_field(field_name)
except FieldDoesNotExist:
return [
checks.Error(
"CurrentSiteManager could not find a field named '%s'." % field_name,
obj=self,
id='sites.E001',
)
]
if not field.many_to_many and not isinstance(field, (models.ForeignKey)):
return [
checks.Error(
"CurrentSiteManager cannot use '%s.%s' as it is not a foreign key or a many-to-many field." % (
self.model._meta.object_name, field_name
),
obj=self,
id='sites.E002',
)
]
return []
def _check_recursion_field_dependecy(self):
res = []
for local_field in self._raw_fields.values():
try:
f = self.model._meta.get_field(local_field.value)
if isinstance(f, CompositeForeignKey):
res.append(
checks.Error(
"the field %s depend on the field %s which is another CompositeForeignKey" % (self.name, local_field),
hint=None,
obj=self,
id='compositefk.E005',
)
)
except FieldDoesNotExist:
pass # _check_to_fields_local_valide already raise errors for this
return res
def _check_to_fields_local_valide(self):
res = []
for local_field in self._raw_fields.values():
if isinstance(local_field, LocalFieldValue):
try:
self.model._meta.get_field(local_field.value)
except FieldDoesNotExist:
res.append(
checks.Error(
"the field %s does not exists on the model %s" % (local_field, self.model),
hint=None,
obj=self,
id='compositefk.E003',
)
)
return res
def is_valid_field(self, model, field):
# Split with maximum splits of 1, so if passed xx__yy__zz, we get [xx, yy__zz]
components = field.split(LOOKUP_SEP, 1)
try:
field = model._meta.get_field(components[0])
# Reverse lookup
if isinstance(field, ForeignObjectRel):
return self.is_valid_field(field.model, components[1])
if field.get_internal_type() in self.related_field_types and len(components) > 1:
return self.is_valid_field(field.related_model, components[1])
return True
except FieldDoesNotExist:
return False
def post_migrate_mpathnode(model):
# Note: model *isn't* a subclass of MPathNode, because django migrations are Weird.
# if not issubclass(model, MPathNode):
# Hence the following workaround:
try:
ltree_field = model._meta.get_field('ltree')
if not isinstance(ltree_field, LTreeField):
return
except FieldDoesNotExist:
return
names = {
"table": quote_ident(model._meta.db_table, connection.connection),
"check_constraint": quote_ident('%s__check_ltree' % model._meta.db_table, connection.connection),
}
cur = connection.cursor()
# Check that the ltree is always consistent with being a child of _parent
cur.execute('''
ALTER TABLE %(table)s ADD CONSTRAINT %(check_constraint)s CHECK (
(parent_id IS NOT NULL AND ltree ~ (parent_id::text || '.*{1}')::lquery)
OR (parent_id IS NULL AND ltree ~ '*{1}'::lquery)
)
''' % names)
def sort_queryset(self, qs):
sort_key = self.request.GET.get('sort')
if sort_key:
plain_key = sort_key[1:] if sort_key.startswith('-') else sort_key
reverse = not (plain_key == sort_key)
if plain_key in self.sortable_fields:
is_text = False
with suppress(FieldDoesNotExist):
is_text = isinstance(qs.model._meta.get_field(plain_key), CharField)
if is_text:
# TODO: this only sorts direct lookups case insensitively
# A sorting field like 'speaker__name' will not be found
qs = qs.annotate(key=Lower(plain_key)).order_by('-key' if reverse else 'key')
else:
qs = qs.order_by(sort_key)
return qs
def _check_field_name(self):
field_name = self._get_field_name()
try:
field = self.model._meta.get_field(field_name)
except FieldDoesNotExist:
return [
checks.Error(
"CurrentSiteManager could not find a field named '%s'." % field_name,
obj=self,
id='sites.E001',
)
]
if not field.many_to_many and not isinstance(field, (models.ForeignKey)):
return [
checks.Error(
"CurrentSiteManager cannot use '%s.%s' as it is not a foreign key or a many-to-many field." % (
self.model._meta.object_name, field_name
),
obj=self,
id='sites.E002',
)
]
return []
def _check_radio_fields_key(self, obj, model, field_name, label):
""" Check that a key of `radio_fields` dictionary is name of existing
field and that the field is a ForeignKey or has `choices` defined. """
try:
field = model._meta.get_field(field_name)
except FieldDoesNotExist:
return refer_to_missing_field(field=field_name, option=label,
model=model, obj=obj, id='admin.E022')
else:
if not (isinstance(field, models.ForeignKey) or field.choices):
return [
checks.Error(
"The value of '%s' refers to '%s', which is not an "
"instance of ForeignKey, and does not have a 'choices' definition." % (
label, field_name
),
obj=obj.__class__,
id='admin.E023',
)
]
else:
return []
def _check_prepopulated_fields_key(self, obj, model, field_name, label):
""" Check a key of `prepopulated_fields` dictionary, i.e. check that it
is a name of existing field and the field is one of the allowed types.
"""
try:
field = model._meta.get_field(field_name)
except FieldDoesNotExist:
return refer_to_missing_field(field=field_name, option=label,
model=model, obj=obj, id='admin.E027')
else:
if isinstance(field, (models.DateTimeField, models.ForeignKey, models.ManyToManyField)):
return [
checks.Error(
"The value of '%s' refers to '%s', which must not be a DateTimeField, "
"a ForeignKey, or a ManyToManyField." % (label, field_name),
obj=obj.__class__,
id='admin.E028',
)
]
else:
return []
def _check_readonly_fields_item(self, obj, model, field_name, label):
if callable(field_name):
return []
elif hasattr(obj, field_name):
return []
elif hasattr(model, field_name):
return []
else:
try:
model._meta.get_field(field_name)
except FieldDoesNotExist:
return [
checks.Error(
"The value of '%s' is not a callable, an attribute of '%s', or an attribute of '%s.%s'." % (
label, obj.__class__.__name__, model._meta.app_label, model._meta.object_name
),
obj=obj.__class__,
id='admin.E035',
)
]
else:
return []
def _check_date_hierarchy(self, obj):
""" Check that date_hierarchy refers to DateField or DateTimeField. """
if obj.date_hierarchy is None:
return []
else:
try:
field = obj.model._meta.get_field(obj.date_hierarchy)
except FieldDoesNotExist:
return refer_to_missing_field(
option='date_hierarchy', field=obj.date_hierarchy,
model=obj.model, obj=obj, id='admin.E127',
)
else:
if not isinstance(field, (models.DateField, models.DateTimeField)):
return must_be('a DateField or DateTimeField', option='date_hierarchy', obj=obj, id='admin.E128')
else:
return []
def validate_readonly_fields(self, cls, model):
" Validate that readonly_fields refers to proper attribute or field. "
if hasattr(cls, "readonly_fields"):
check_isseq(cls, "readonly_fields", cls.readonly_fields)
for idx, field in enumerate(cls.readonly_fields):
if not callable(field):
if not hasattr(cls, field):
if not hasattr(model, field):
try:
model._meta.get_field(field)
except FieldDoesNotExist:
raise ImproperlyConfigured(
"%s.readonly_fields[%d], %r is not a callable or "
"an attribute of %r or found in the model %r."
% (cls.__name__, idx, field, cls.__name__, model._meta.object_name)
)
def validate_list_display(self, cls, model):
" Validate that list_display only contains fields or usable attributes. "
if hasattr(cls, 'list_display'):
check_isseq(cls, 'list_display', cls.list_display)
for idx, field in enumerate(cls.list_display):
if not callable(field):
if not hasattr(cls, field):
if not hasattr(model, field):
try:
model._meta.get_field(field)
except FieldDoesNotExist:
raise ImproperlyConfigured(
"%s.list_display[%d], %r is not a callable or "
"an attribute of %r or found in the model %r."
% (cls.__name__, idx, field, cls.__name__, model._meta.object_name)
)
else:
# getattr(model, field) could be an X_RelatedObjectsDescriptor
f = fetch_attr(cls, model, "list_display[%d]" % idx, field)
if isinstance(f, models.ManyToManyField):
raise ImproperlyConfigured(
"'%s.list_display[%d]', '%s' is a ManyToManyField "
"which is not supported."
% (cls.__name__, idx, field)
)