86
80
base_meta = getattr(new_class, '_meta', None)
82
# Look for an application configuration to attach the model to.
83
app_config = apps.get_containing_app_config(module)
88
85
if getattr(meta, 'app_label', None) is None:
89
# Figure out the app_label by looking one level up.
90
# For 'django.contrib.sites.models', this would be 'sites'.
91
model_module = sys.modules[new_class.__module__]
92
kwargs = {"app_label": model_module.__name__.split('.')[-2]}
87
if app_config is None:
88
# If the model is imported before the configuration for its
89
# application is created (#21719), or isn't in an installed
90
# application (#21680), use the legacy logic to figure out the
91
# app_label by looking one level up from the package or module
92
# named 'models'. If no such package or module exists, fall
93
# back to looking one level up from the module this model is
96
# For 'django.contrib.sites.models', this would be 'sites'.
97
# For 'geo.models.places' this would be 'geo'.
100
"Model class %s.%s doesn't declare an explicit app_label "
101
"and either isn't in an application in INSTALLED_APPS or "
102
"else was imported before its application was loaded. " %
105
msg += "Its app_label will be set to None in Django 1.9."
107
msg += "This will no longer be supported in Django 1.9."
108
warnings.warn(msg, RemovedInDjango19Warning, stacklevel=2)
110
model_module = sys.modules[new_class.__module__]
111
package_components = model_module.__name__.split('.')
112
package_components.reverse() # find the last occurrence of 'models'
114
app_label_index = package_components.index(MODELS_MODULE_NAME) + 1
117
kwargs = {"app_label": package_components[app_label_index]}
120
kwargs = {"app_label": app_config.label}
96
125
new_class.add_to_class('_meta', Options(meta, **kwargs))
98
new_class.add_to_class('DoesNotExist', subclass_exception(str('DoesNotExist'),
100
for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
101
or (ObjectDoesNotExist,),
102
module, attached_to=new_class))
103
new_class.add_to_class('MultipleObjectsReturned', subclass_exception(str('MultipleObjectsReturned'),
104
tuple(x.MultipleObjectsReturned
105
for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
106
or (MultipleObjectsReturned,),
107
module, attached_to=new_class))
127
new_class.add_to_class(
131
tuple(x.DoesNotExist for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (ObjectDoesNotExist,),
133
attached_to=new_class))
134
new_class.add_to_class(
135
'MultipleObjectsReturned',
137
str('MultipleObjectsReturned'),
138
tuple(x.MultipleObjectsReturned for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (MultipleObjectsReturned,),
140
attached_to=new_class))
108
141
if base_meta and not base_meta.abstract:
109
142
# Non-abstract child classes inherit some attributes from their
110
143
# non-abstract parent (unless an ABC comes before it in the
887
def date_error_message(self, lookup_type, field, unique_for):
932
def date_error_message(self, lookup_type, field_name, unique_for):
888
933
opts = self._meta
889
return _("%(field_name)s must be unique for %(date_field)s %(lookup)s.") % {
890
'field_name': six.text_type(capfirst(opts.get_field(field).verbose_name)),
891
'date_field': six.text_type(capfirst(opts.get_field(unique_for).verbose_name)),
892
'lookup': lookup_type,
934
field = opts.get_field(field_name)
935
return ValidationError(
936
message=field.error_messages['unique_for_date'],
937
code='unique_for_date',
940
'model_name': six.text_type(capfirst(opts.verbose_name)),
941
'lookup_type': lookup_type,
943
'field_label': six.text_type(capfirst(field.verbose_name)),
944
'date_field': unique_for,
945
'date_field_label': six.text_type(capfirst(opts.get_field(unique_for).verbose_name)),
895
949
def unique_error_message(self, model_class, unique_check):
896
950
opts = model_class._meta
897
model_name = capfirst(opts.verbose_name)
954
'model_class': model_class,
955
'model_name': six.text_type(capfirst(opts.verbose_name)),
956
'unique_check': unique_check,
900
960
if len(unique_check) == 1:
901
field_name = unique_check[0]
902
field = opts.get_field(field_name)
903
field_label = capfirst(field.verbose_name)
904
# Insert the error into the error dict, very sneaky
905
return field.error_messages['unique'] % {
906
'model_name': six.text_type(model_name),
907
'field_label': six.text_type(field_label)
961
field = opts.get_field(unique_check[0])
962
params['field_label'] = six.text_type(capfirst(field.verbose_name))
963
return ValidationError(
964
message=field.error_messages['unique'],
909
969
# unique_together
911
971
field_labels = [capfirst(opts.get_field(f).verbose_name) for f in unique_check]
912
field_labels = get_text_list(field_labels, _('and'))
913
return _("%(model_name)s with this %(field_label)s already exists.") % {
914
'model_name': six.text_type(model_name),
915
'field_label': six.text_type(field_labels)
972
params['field_labels'] = six.text_type(get_text_list(field_labels, _('and')))
973
return ValidationError(
974
message=_("%(model_name)s with this %(field_labels)s already exists."),
975
code='unique_together',
918
979
def full_clean(self, exclude=None, validate_unique=True):
975
1038
raise ValidationError(errors)
1041
def check(cls, **kwargs):
1043
errors.extend(cls._check_swappable())
1044
errors.extend(cls._check_model())
1045
errors.extend(cls._check_managers(**kwargs))
1046
if not cls._meta.swapped:
1047
errors.extend(cls._check_fields(**kwargs))
1048
errors.extend(cls._check_m2m_through_same_relationship())
1049
clash_errors = cls._check_id_field() + cls._check_field_name_clashes()
1050
errors.extend(clash_errors)
1051
# If there are field name clashes, hide consequent column name
1053
if not clash_errors:
1054
errors.extend(cls._check_column_name_clashes())
1055
errors.extend(cls._check_index_together())
1056
errors.extend(cls._check_unique_together())
1057
errors.extend(cls._check_ordering())
1062
def _check_swappable(cls):
1063
""" Check if the swapped model exists. """
1066
if cls._meta.swapped:
1068
apps.get_model(cls._meta.swapped)
1072
"'%s' is not of the form 'app_label.app_name'." % cls._meta.swappable,
1079
app_label, model_name = cls._meta.swapped.split('.')
1082
("'%s' references '%s.%s', which has not been installed, or is abstract.") % (
1083
cls._meta.swappable, app_label, model_name
1093
def _check_model(cls):
1096
if cls._meta.local_fields or cls._meta.local_many_to_many:
1099
"Proxy model '%s' contains model fields." % cls.__name__,
1108
def _check_managers(cls, **kwargs):
1109
""" Perform all manager checks. """
1112
managers = cls._meta.concrete_managers + cls._meta.abstract_managers
1113
for __, __, manager in managers:
1114
errors.extend(manager.check(**kwargs))
1118
def _check_fields(cls, **kwargs):
1119
""" Perform all field checks. """
1122
for field in cls._meta.local_fields:
1123
errors.extend(field.check(**kwargs))
1124
for field in cls._meta.local_many_to_many:
1125
errors.extend(field.check(from_model=cls, **kwargs))
1129
def _check_m2m_through_same_relationship(cls):
1130
""" Check if no relationship model is used by more than one m2m field.
1134
seen_intermediary_signatures = []
1136
fields = cls._meta.local_many_to_many
1138
# Skip when the target model wasn't found.
1139
fields = (f for f in fields if isinstance(f.rel.to, ModelBase))
1141
# Skip when the relationship model wasn't found.
1142
fields = (f for f in fields if isinstance(f.rel.through, ModelBase))
1145
signature = (f.rel.to, cls, f.rel.through)
1146
if signature in seen_intermediary_signatures:
1149
("The model has two many-to-many relations through "
1150
"the intermediate model '%s.%s'.") % (
1151
f.rel.through._meta.app_label,
1152
f.rel.through._meta.object_name
1160
seen_intermediary_signatures.append(signature)
1164
def _check_id_field(cls):
1165
""" Check if `id` field is a primary key. """
1167
fields = list(f for f in cls._meta.local_fields
1168
if f.name == 'id' and f != cls._meta.pk)
1169
# fields is empty or consists of the invalid "id" field
1170
if fields and not fields[0].primary_key and cls._meta.pk.name == 'id':
1173
("'id' can only be used as a field name if the field also "
1174
"sets 'primary_key=True'."),
1184
def _check_field_name_clashes(cls):
1188
used_fields = {} # name or attname -> field
1190
# Check that multi-inheritance doesn't cause field name shadowing.
1191
for parent in cls._meta.parents:
1192
for f in parent._meta.local_fields:
1193
clash = used_fields.get(f.name) or used_fields.get(f.attname) or None
1197
("The field '%s' from parent model "
1198
"'%s' clashes with the field '%s' "
1199
"from parent model '%s'.") % (
1200
clash.name, clash.model._meta,
1201
f.name, f.model._meta
1208
used_fields[f.name] = f
1209
used_fields[f.attname] = f
1211
# Check that fields defined in the model don't clash with fields from
1213
for f in cls._meta.local_fields:
1214
clash = used_fields.get(f.name) or used_fields.get(f.attname) or None
1215
# Note that we may detect clash between user-defined non-unique
1216
# field "id" and automatically added unique field "id", both
1217
# defined at the same model. This special case is considered in
1218
# _check_id_field and here we ignore it.
1219
id_conflict = (f.name == "id" and
1220
clash and clash.name == "id" and clash.model == cls)
1221
if clash and not id_conflict:
1224
("The field '%s' clashes with the field '%s' "
1225
"from model '%s'.") % (
1226
f.name, clash.name, clash.model._meta
1233
used_fields[f.name] = f
1234
used_fields[f.attname] = f
1239
def _check_column_name_clashes(cls):
1240
# Store a list of column names which have already been used by other fields.
1241
used_column_names = []
1244
for f in cls._meta.local_fields:
1245
_, column_name = f.get_attname_column()
1247
# Ensure the column name is not already in use.
1248
if column_name and column_name in used_column_names:
1251
"Field '%s' has column name '%s' that is used by another field." % (f.name, column_name),
1252
hint="Specify a 'db_column' for the field.",
1258
used_column_names.append(column_name)
1263
def _check_index_together(cls):
1264
""" Check the value of "index_together" option. """
1265
if not isinstance(cls._meta.index_together, (tuple, list)):
1268
"'index_together' must be a list or tuple.",
1275
elif any(not isinstance(fields, (tuple, list))
1276
for fields in cls._meta.index_together):
1279
"All 'index_together' elements must be lists or tuples.",
1288
for fields in cls._meta.index_together:
1289
errors.extend(cls._check_local_fields(fields, "index_together"))
1293
def _check_unique_together(cls):
1294
""" Check the value of "unique_together" option. """
1295
if not isinstance(cls._meta.unique_together, (tuple, list)):
1298
"'unique_together' must be a list or tuple.",
1305
elif any(not isinstance(fields, (tuple, list))
1306
for fields in cls._meta.unique_together):
1309
"All 'unique_together' elements must be lists or tuples.",
1318
for fields in cls._meta.unique_together:
1319
errors.extend(cls._check_local_fields(fields, "unique_together"))
1323
def _check_local_fields(cls, fields, option):
1324
from django.db import models
1327
for field_name in fields:
1329
field = cls._meta.get_field(field_name,
1331
except models.FieldDoesNotExist:
1334
"'%s' refers to the non-existent field '%s'." % (option, field_name),
1341
if isinstance(field.rel, models.ManyToManyRel):
1344
("'%s' refers to a ManyToManyField '%s', but "
1345
"ManyToManyFields are not permitted in '%s'.") % (
1346
option, field_name, option
1356
def _check_ordering(cls):
1357
""" Check "ordering" option -- is it a list of strings and do all fields
1360
from django.db.models import FieldDoesNotExist
1362
if not cls._meta.ordering:
1365
if not isinstance(cls._meta.ordering, (list, tuple)):
1368
("'ordering' must be a tuple or list "
1369
"(even if you want to order by only one field)."),
1378
fields = cls._meta.ordering
1381
fields = (f for f in fields if f != '?')
1383
# Convert "-field" to "field".
1384
fields = ((f[1:] if f.startswith('-') else f) for f in fields)
1386
fields = (f for f in fields if
1387
f != '_order' or not cls._meta.order_with_respect_to)
1389
# Skip ordering in the format field1__field2 (FIXME: checking
1390
# this format would be nice, but it's a little fiddly).
1391
fields = (f for f in fields if '__' not in f)
1393
# Skip ordering on pk. This is always a valid order_by field
1394
# but is an alias and therefore won't be found by opts.get_field.
1395
fields = (f for f in fields if f != 'pk')
1397
for field_name in fields:
1399
cls._meta.get_field(field_name, many_to_many=False)
1400
except FieldDoesNotExist:
1401
if field_name.endswith('_id'):
1403
field = cls._meta.get_field(field_name[:-3], many_to_many=False)
1404
except FieldDoesNotExist:
1407
if field.attname == field_name:
1411
"'ordering' refers to the non-existent field '%s'." % field_name,
978
1420
############################################
979
1421
# HELPER FUNCTIONS (CURRIED MODEL METHODS) #