Using is_safe with mark_safe() is redundant, so you probably don't see the difference.
As noted in the section you are attached to down where it talks about mark_safe() :
In this case, there is no need to worry about the is_safe attribute (although including it will not hurt anything). Whenever you manually handle auto-escaping problems and return a safe string, the is_safe attribute will not change anything anyway.
is_safe is just a way to automatically mark the return value of a function as safe, given that all external inputs were already safe. Django will still autoescape everything that was input, but it will not try to avoid the other parts that were subsequently added by your function.
mark_safe() , on the other hand, confirms that the output is safe regardless of whether the inputs were safe - this is a much stronger requirement that you need to fulfill if you intend to use it.
Amber source share