Repository: wagtail/wagtail
File: wagtail/images/models.py (Python)

Code before:
                set(constraint) == {"image", "filter_spec", "focal_point_key"}
                for constraint in cls._meta.unique_together
            )

            # We only include fields to check if they are a UniqueConstraint, a
            # nd they have no condition on them.
            unique_constraint_fields = [
                constraint.fields
                for constraint in cls._meta.constraints
                if (
                    isinstance(constraint, UniqueConstraint)
                    and constraint.condition is None
                )
            ]
            in_unique_constraint = any(
                set(constraint) == {"image", "filter_spec", "focal_point_key"}
                for constraint in unique_constraint_fields
            )

            # We check for some kind of unique constraint, whether in unique together or
            # as part of the constraints.
            if not in_unique_together and not in_unique_constraint:
                errors.append(
                    checks.Error(
                        "Custom rendition model %r has an invalid unique_together setting"
                        % cls,
                        hint="Custom rendition models must include the constraint "
                        "('image', 'filter_spec', 'focal_point_key') in their unique_together definition, or as part of a unique constraint.",
                        obj=cls,
                        id="wagtailimages.E001",
                    )
                )

        return errors

    @staticmethod
    def construct_cache_key(image, filter_cache_key, filter_spec):
        return "wagtail-rendition-" + "-".join(
            [str(image.id), image.file_hash, filter_cache_key, filter_spec]
        )

    @classproperty
    def cache_backend(cls) -> BaseCache:
        try:
            return caches["renditions"]
        except InvalidCacheBackendError:
            return caches[DEFAULT_CACHE_ALIAS]

    def get_cache_key(self):
        return self.construct_cache_key(
            self.image, self.focal_point_key, self.filter_spec

Review comment (suggestion):
**Suggestion:** should we change this to _only_ refer to UniqueConstraint? This pushes people towards the way [the way Django recommends you define constraints](https://docs.djangoproject.com/en/5.1/ref/models/options/#unique-together).

Code after:
            # a `UniqueConstraint` in `constraints`.
            unique_constraint_fields = {"image", "filter_spec", "focal_point_key"}
            in_unique_together = any(
                set(constraint) == unique_constraint_fields
                for constraint in cls._meta.unique_together
            )
            in_unique_constraint = any(
                isinstance(constraint, models.UniqueConstraint)
                and constraint.condition is None
                and set(constraint.fields) == unique_constraint_fields
                for constraint in cls._meta.constraints
            )

            if not in_unique_together and not in_unique_constraint:
                errors.append(
                    checks.Error(
                        "Custom rendition model '%s' must include a unique constraint "
                        "on the 'image', 'filter_spec', and 'focal_point_key' fields."
                        % cls._meta.label,
                        hint=(
                            "Add models.UniqueConstraint(fields={"
                            '"image", "filter_spec", "focal_point_key"}, '
                            'name="unique_rendition") to %s.Meta.constraints.'
                            % (cls.__name__,)
                        ),
                        obj=cls,
                        id="wagtailimages.E001",
                    )
                )

        return errors

    @staticmethod
    def construct_cache_key(image, filter_cache_key, filter_spec):
        return "wagtail-rendition-" + "-".join(
            [str(image.id), image.file_hash, filter_cache_key, filter_spec]
        )

    @classproperty
    def cache_backend(cls) -> BaseCache:
        try:
            return caches["renditions"]
        except InvalidCacheBackendError:
            return caches[DEFAULT_CACHE_ALIAS]

    def get_cache_key(self):
        return self.construct_cache_key(
            self.image, self.focal_point_key, self.filter_spec
        )

    def purge_from_cache(self):