diff --git a/CHANGELOG.md b/CHANGELOG.md
index 16a491f84b89cf355eef3a15a554f6ef68ab1f28..e9be3af5e8af94fdae3047da28ca16a191387d9f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,7 @@
-# v2.24.0
+# v2.23.1
 
-* completely overhauled [overload](https://satella.readthedocs.io/en/latest/coding/functions.html#function-overloading), 
-  ie. fixed #57.
+* added OnStrOnlyName
+
+[//]: # (* completely overhauled [overload](https://satella.readthedocs.io/en/latest/coding/functions.html#function-overloading), )
+
+[//]: # (  ie. fixed #57.)
diff --git a/docs/coding/structures.rst b/docs/coding/structures.rst
index 0cf7a60e782828c7c7ae9427d1cab46e9f9af031..b1e94aa1296f021d96568ec3c31326f0ec1f0415 100644
--- a/docs/coding/structures.rst
+++ b/docs/coding/structures.rst
@@ -95,6 +95,12 @@ Mixins are classes whose constructor you do not need to invoke. They magically
 endow your class with chosen properties, often by overloading their specific
 special methods.
 
+OnStrOnlyName
+-------------
+
+.. autoclass:: satella.coding.structures.OnStrOnlyName
+    :members:
+
 HashableMixin
 -------------
 
diff --git a/satella/__init__.py b/satella/__init__.py
index 1c24e3331d9c331f3786944f0d8c003c36aa6c6a..6b8976459efe6be291bd4e6dff8fe1f91642a234 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1 +1 @@
-__version__ = '2.23.1b1'
+__version__ = '2.23.1'
diff --git a/satella/coding/structures/__init__.py b/satella/coding/structures/__init__.py
index 9677096d43acfc65c9268f8c30b5047c67c8f1d3..15abee15ade56975219ab6caafd0cdcccce5299c 100644
--- a/satella/coding/structures/__init__.py
+++ b/satella/coding/structures/__init__.py
@@ -6,7 +6,7 @@ from .heaps import Heap, SetHeap, TimeBasedHeap, TimeBasedSetHeap
 from .immutable import Immutable, frozendict, NotEqualToAnything, NOT_EQUAL_TO_ANYTHING
 from .mixins import OmniHashableMixin, ReprableMixin, StrEqHashableMixin, ComparableIntEnum, \
     HashableIntEnum, ComparableAndHashableBy, ComparableAndHashableByInt, ComparableEnum, \
-    HashableMixin, ComparableAndHashableByStr, DictionaryEQAble
+    HashableMixin, ComparableAndHashableByStr, DictionaryEQAble, OnStrOnlyName
 from .proxy import Proxy
 from .queues import Subqueue
 from .ranking import Ranking
@@ -22,7 +22,7 @@ from .zip_dict import SetZip
 from .push_iterable import PushIterable
 
 __all__ = [
-    'PushIterable',
+    'PushIterable', 'OnStrOnlyName',
     'Vector', 'SetZip',
     'DBStorage', 'SyncableDroppable',
     'LRU',
diff --git a/satella/coding/structures/mixins/__init__.py b/satella/coding/structures/mixins/__init__.py
index 948d863102e452b3f9ba3c5ea8cf807423e2cbfa..94121dc4f95c0f11e6050a4d09eccf876dc84094 100644
--- a/satella/coding/structures/mixins/__init__.py
+++ b/satella/coding/structures/mixins/__init__.py
@@ -1,4 +1,4 @@
-from .enums import ComparableEnum, ComparableIntEnum, HashableIntEnum
+from .enums import ComparableEnum, ComparableIntEnum, HashableIntEnum, OnStrOnlyName
 from .hashable import ComparableAndHashableBy, ComparableAndHashableByInt, \
     OmniHashableMixin, HashableMixin, ComparableAndHashableByStr
 from .strings import ReprableMixin, StrEqHashableMixin
@@ -7,4 +7,4 @@ from .eqable import DictionaryEQAble
 __all__ = ['ComparableIntEnum', 'ComparableEnum', 'ComparableAndHashableBy',
            'HashableIntEnum', 'ComparableAndHashableByInt', 'OmniHashableMixin',
            'ReprableMixin', 'StrEqHashableMixin', 'HashableMixin',
-           'ComparableAndHashableByStr', 'DictionaryEQAble']
+           'ComparableAndHashableByStr', 'DictionaryEQAble', 'OnStrOnlyName']
diff --git a/satella/coding/structures/mixins/enums.py b/satella/coding/structures/mixins/enums.py
index 7dd5f95f64b411d8e3cff504ada7be5eeb1ac96d..4ebe734ec66980d21a4f86090dab1e605d1159c1 100644
--- a/satella/coding/structures/mixins/enums.py
+++ b/satella/coding/structures/mixins/enums.py
@@ -87,3 +87,23 @@ class ComparableIntEnum(HashableIntEnum):
         if isinstance(other, (int, float)):
             return self.value == other
         return self.value == int(other)
+
+
+class OnStrOnlyName:
+    """
+    A mix-in to add the following functionality to your class.
+
+    tl;dr - the name will be used instead of ClassName.name.
+
+    >>> from enum import Enum
+    >>> class MyEnum(OnStrOnlyName, Enum):
+    >>>     A = 0
+    >>>     B = 1
+    >>>     C = 'test'
+    >>> assert str(MyEnum.A) == 'A'
+    >>> assert str(MyEnum.B) == 'B'
+    >>> assert str(MyEnum.C) == 'test'
+    """
+
+    def __str__(self) -> str:
+        return self.name
diff --git a/tests/test_coding/test_structures.py b/tests/test_coding/test_structures.py
index 9acf9550ec0c588a56d2356e0a388c3e206c048e..878a76babb84951ecad79dfb938718750d3cf2ee 100644
--- a/tests/test_coding/test_structures.py
+++ b/tests/test_coding/test_structures.py
@@ -4,7 +4,7 @@ import copy
 import math
 import time
 import unittest
-
+from enum import Enum
 from unittest import mock
 
 from satella.coding.concurrent import call_in_separate_thread
@@ -15,11 +15,39 @@ from satella.coding.structures import TimeBasedHeap, Heap, typednamedtuple, \
     CacheDict, StrEqHashableMixin, ComparableIntEnum, HashableIntEnum, ComparableAndHashableBy, \
     ComparableAndHashableByInt, SparseMatrix, ExclusiveWritebackCache, Subqueue, \
     CountingDict, ComparableEnum, LRU, LRUCacheDict, Vector, DefaultDict, PushIterable, \
-    ComparableAndHashableByStr, NotEqualToAnything, NOT_EQUAL_TO_ANYTHING, DictionaryEQAble, SetZip
+    ComparableAndHashableByStr, NotEqualToAnything, NOT_EQUAL_TO_ANYTHING, DictionaryEQAble, SetZip, OnStrOnlyName
+
+
+def continue_testing_omni(self, omni_class):
+    e1 = omni_class(2)
+    e2 = omni_class(1)
+    e3 = omni_class(1)
+
+    self.assertEqual(e2, e3)
+    self.assertNotEqual(e1, e2)
+    self.assertNotEqual(e1, e3)
+
+    a = {
+        e1: '1', e2: '2', e3: '3'
+    }
+
+    self.assertEqual(a[e1], '1')
+    self.assertEqual(hash(e1), hash(2))
 
 
 class TestStructures(unittest.TestCase):
 
+    def test_onstronlyname(self):
+
+        class MyEnum(OnStrOnlyName, Enum):
+            A = 0
+            B = 1
+            C = 'test'
+
+        self.assertEqual(str(MyEnum.A), 'A')
+        self.assertEqual(str(MyEnum.B), 'B')
+        self.assertEqual(str(MyEnum.C), 'C')
+
     def test_zip(self):
         a = set([1,2, 3])
         b = set([3,4,5])
@@ -694,22 +722,6 @@ class TestStructures(unittest.TestCase):
         self.assertEqual(hash(a), hash(b))
         self.assertRaises(TypeError, lambda: a.update({3: 5}))
 
-    def continue_testing_omni(self, Omni):
-        e1 = Omni(2)
-        e2 = Omni(1)
-        e3 = Omni(1)
-
-        self.assertEqual(e2, e3)
-        self.assertNotEqual(e1, e2)
-        self.assertNotEqual(e1, e3)
-
-        a = {
-            e1: '1', e2: '2', e3: '3'
-        }
-
-        self.assertEqual(a[e1], '1')
-        self.assertEqual(hash(e1), hash(2))
-
     def test_omni_not_filled_in_fields(self):
         class Omni1(OmniHashableMixin):
             _HASH_FIELDS_TO_USE = 'a'
@@ -744,7 +756,7 @@ class TestStructures(unittest.TestCase):
             def __init__(self, a):
                 self.a = a
 
-        self.continue_testing_omni(Omni)
+        continue_testing_omni(self, Omni)
 
     def test_omni(self):
         class Omni(OmniHashableMixin):
@@ -752,7 +764,7 @@ class TestStructures(unittest.TestCase):
 
             def __init__(self, a):
                 self.a = a
-        self.continue_testing_omni(Omni)
+        continue_testing_omni(self, Omni)
 
     def test_tbsh(self):
         tbh = TimeBasedSetHeap()