Attempts to load and verify the CTE node parameters. Will use
            default values for all missing parameters, and raise an exception if
            a parameter's value cannot be verified. This method will only
            perform these actions once, and set the :attr:`_parameters_checked`
            attribute to ``True`` upon its first success.

def _ensure_parameters(self):
        """ Attempts to load and verify the CTE node parameters. Will use
            default values for all missing parameters, and raise an exception if
            a parameter's value cannot be verified. This method will only
            perform these actions once, and set the :attr:`_parameters_checked`
            attribute to ``True`` upon its first success.
        """

        if hasattr(self, "_parameters_checked"):
            return

        if (
            not hasattr(self.model, "_cte_node_table")
            or self.model._cte_node_table is None
        ):
            setattr(self.model, "_cte_node_table", self.DEFAULT_TABLE_NAME)

        if (
            not hasattr(self.model, "_cte_node_depth")
            or self.model._cte_node_depth is None
        ):
            setattr(self.model, "_cte_node_depth", self.VIRTUAL_FIELD_DEPTH)

        if (
            not hasattr(self.model, "_cte_node_path")
            or self.model._cte_node_depth is None
        ):
            setattr(self.model, "_cte_node_path", self.VIRTUAL_FIELD_PATH)

        if (
            not hasattr(self.model, "_cte_node_ordering")
            or self.model._cte_node_ordering is None
        ):
            setattr(self.model, "_cte_node_ordering", self.VIRTUAL_FIELD_ORDERING)

        if (
            not hasattr(self.model, "_cte_node_traversal")
            or self.model._cte_node_traversal is None
        ):
            setattr(self.model, "_cte_node_traversal", self.DEFAULT_TREE_TRAVERSAL)

        if (
            not hasattr(self.model, "_cte_node_children")
            or self.model._cte_node_children is None
        ):
            setattr(self.model, "_cte_node_children", self.DEFAULT_CHILDREN_NAME)

        if not hasattr(self.model, "_cte_node_primary_key_type"):
            setattr(self.model, "_cte_node_primary_key_type", None)

        # Determine the parent foreign key field name, either
        # explicitly specified, or the first foreign key to 'self'.
        # If we need to determine, then we set the attribute for future
        # reference.
        if (
            not hasattr(self.model, "_cte_node_parent")
            or self.model._cte_node_parent is None
        ):
            found = False
            for f in self.model._meta.fields:
                if isinstance(f, ForeignKey):
                    if f.remote_field.model == self.model:
                        setattr(self.model, "_cte_node_parent", f.name)
                        found = True
            if not found:
                raise ImproperlyConfigured(
                    _(
                        "CTENode must have a Foreign Key to self for the parent "
                        "relation."
                    )
                )

        try:
            parent_field = self.model._meta.get_field(self.model._cte_node_parent)
        except FieldDoesNotExist:
            raise ImproperlyConfigured(
                "".join(
                    [
                        _(
                            "CTENode._cte_node_parent must specify a Foreign Key"
                            " to self, instead it is: "
                        ),
                        self.model._cte_node_parent,
                    ]
                )
            )

        # Ensure parent relation is a Foreign Key to self.
        if not parent_field.remote_field.model == self.model:
            raise ImproperlyConfigured(
                "".join(
                    [
                        _(
                            "CTENode._cte_node_parent must specify a Foreign Key"
                            " to self, instead it is: "
                        ),
                        self.model._cte_node_parent,
                    ]
                )
            )

        # Record the parent field attribute name for future reference.
        setattr(
            self.model,
            "_cte_node_parent_attname",
            self.model._meta.get_field(self.model._cte_node_parent).attname,
        )

        # Ensure traversal choice is valid.
        traversal_choices = [choice[0] for choice in self.TREE_TRAVERSAL_CHOICES]
        if self.model._cte_node_traversal not in traversal_choices:
            raise ImproperlyConfigured(
                " ".join(
                    [
                        "CTENode._cte_node_traversal must be one of [",
                        ", ".join(traversal_choices),
                        "]; instead it is:",
                        self.model._cte_node_traversal,
                    ]
                )
            )

        # Ensure delete choice is valid.
        if (
            not hasattr(self.model, "_cte_node_delete_method")
            or self.model._cte_node_delete_method is None
        ):
            setattr(self.model, "_cte_node_delete_method", self.DEFAULT_DELETE_METHOD)
        else:
            # Ensure specified method is valid.
            method_choices = [dm[0] for dm in self.DELETE_METHOD_CHOICES]
            if self.model._cte_node_delete_method not in method_choices:
                raise ImproperlyConfigured(
                    " ".join(
                        [
                            "delete method must be one of [",
                            ", ".join(method_choices),
                            "]; instead it is:",
                            self.model._cte_node_delete_method,
                        ]
                    )
                )

        setattr(self, "_parameters_checked", True)