Attempts to read the virtual fields from the given `node` in order
            to ensure they exist, resulting in an early :class:`AttributeError`
            exception in case of missing virtual fields. This method requires
            several parameters, and thus invoked :meth:`_ensure_parameters`
            first, possibly resulting in an :class:`ImproperlyConfigured`
            exception being raised.

            :param node: the :class:`CTENode` for which to verify that the
                virtual fields are present.

def _ensure_virtual_fields(self, node):
        """ Attempts to read the virtual fields from the given `node` in order
            to ensure they exist, resulting in an early :class:`AttributeError`
            exception in case of missing virtual fields. This method requires
            several parameters, and thus invoked :meth:`_ensure_parameters`
            first, possibly resulting in an :class:`ImproperlyConfigured`
            exception being raised.

            :param node: the :class:`CTENode` for which to verify that the
                virtual fields are present.
        """
        # Uses several _cte_node_* parameters, so ensure they exist.
        self._ensure_parameters()
        for vf in [
            self.model._cte_node_depth,
            self.model._cte_node_path,
            self.model._cte_node_ordering,
        ]:
            if not hasattr(node, vf):
                raise FieldError(
                    _(
                        "CTENode objects must be loaded from the database before "
                        "they can be used."
                    )
                )