Return a list of checks to perform. Since validate_unique() could be called from a ModelForm, some fields may have been excluded; we can't perform a unique check on a model that is missing fields involved in that check. Fields that did not validate should also be exc
(self, exclude=None, include_meta_constraints=False)
| 1464 | raise ValidationError(errors) |
| 1465 | |
| 1466 | def _get_unique_checks(self, exclude=None, include_meta_constraints=False): |
| 1467 | """ |
| 1468 | Return a list of checks to perform. Since validate_unique() could be |
| 1469 | called from a ModelForm, some fields may have been excluded; we can't |
| 1470 | perform a unique check on a model that is missing fields involved |
| 1471 | in that check. Fields that did not validate should also be excluded, |
| 1472 | but they need to be passed in via the exclude argument. |
| 1473 | """ |
| 1474 | if exclude is None: |
| 1475 | exclude = set() |
| 1476 | unique_checks = [] |
| 1477 | |
| 1478 | unique_togethers = [(self.__class__, self._meta.unique_together)] |
| 1479 | constraints = [] |
| 1480 | if include_meta_constraints: |
| 1481 | constraints = [(self.__class__, self._meta.total_unique_constraints)] |
| 1482 | for parent_class in self._meta.all_parents: |
| 1483 | if parent_class._meta.unique_together: |
| 1484 | unique_togethers.append( |
| 1485 | (parent_class, parent_class._meta.unique_together) |
| 1486 | ) |
| 1487 | if include_meta_constraints and parent_class._meta.total_unique_constraints: |
| 1488 | constraints.append( |
| 1489 | (parent_class, parent_class._meta.total_unique_constraints) |
| 1490 | ) |
| 1491 | |
| 1492 | for model_class, unique_together in unique_togethers: |
| 1493 | for check in unique_together: |
| 1494 | if not any(name in exclude for name in check): |
| 1495 | # Add the check if the field isn't excluded. |
| 1496 | unique_checks.append((model_class, tuple(check))) |
| 1497 | |
| 1498 | if include_meta_constraints: |
| 1499 | for model_class, model_constraints in constraints: |
| 1500 | for constraint in model_constraints: |
| 1501 | if not any(name in exclude for name in constraint.fields): |
| 1502 | unique_checks.append((model_class, constraint.fields)) |
| 1503 | |
| 1504 | # These are checks for the unique_for_<date/year/month>. |
| 1505 | date_checks = [] |
| 1506 | |
| 1507 | # Gather a list of checks for fields declared as unique and add them to |
| 1508 | # the list of checks. |
| 1509 | |
| 1510 | fields_with_class = [(self.__class__, self._meta.local_fields)] |
| 1511 | for parent_class in self._meta.all_parents: |
| 1512 | fields_with_class.append((parent_class, parent_class._meta.local_fields)) |
| 1513 | |
| 1514 | for model_class, fields in fields_with_class: |
| 1515 | for f in fields: |
| 1516 | name = f.name |
| 1517 | if name in exclude: |
| 1518 | continue |
| 1519 | if isinstance(f, CompositePrimaryKey): |
| 1520 | names = tuple(field.name for field in f.fields) |
| 1521 | if exclude.isdisjoint(names): |
| 1522 | unique_checks.append((model_class, names)) |
| 1523 | continue |