diff --git a/README.rst b/README.rst
index 67946435..19810f4c 100644
--- a/README.rst
+++ b/README.rst
@@ -1420,6 +1420,20 @@ This produces:
     WHERE "date">NOW()-7 
     GROUP BY "col1","col2"
 
+Inserting dictionaries
+""""""""""""""""
+
+There's a simple convenience function to insert dicts with ``pypika.Query.into("mytable").insert_dict()``.
+
+.. code-block:: python
+    Query.into(Table("foo")).insert_dict({"value": 42, "created_at": datetime(2024, 3, 15)})
+
+This produces:
+
+.. code-block:: sql
+    INSERT INTO "foo" ("value", "created_at")
+        VALUES (42, '2024-03-15T00:00:00')
+
 .. _tutorial_end:
 
 .. _contributing_start: 
diff --git a/pypika/queries.py b/pypika/queries.py
index d7861200..c410592f 100644
--- a/pypika/queries.py
+++ b/pypika/queries.py
@@ -1,6 +1,6 @@
 from copy import copy
 from functools import reduce
-from typing import Any, List, Optional, Sequence, Tuple as TypedTuple, Type, Union
+from typing import Any, List, Optional, Sequence, Tuple as TypedTuple, Type, Union, Set, Dict
 
 from pypika.enums import Dialects, JoinType, ReferenceOption, SetOperation
 from pypika.terms import (
@@ -750,7 +750,7 @@ def __init__(
         self._select_star_tables = set()
         self._mysql_rollup = False
         self._select_into = False
-
+        self._using_insert_dict = False
         self._subquery_count = 0
         self._foreign_table = False
 
@@ -890,6 +890,9 @@ def columns(self, *terms: Any) -> "QueryBuilder":
         if self._insert_table is None:
             raise AttributeError("'Query' object has no attribute '%s'" % "insert")
 
+        if self._using_insert_dict:
+            raise QueryException("Cannot mix use of columns() and insert_dict()")
+
         if terms and isinstance(terms[0], (list, tuple)):
             terms = terms[0]
 
@@ -903,6 +906,15 @@ def insert(self, *terms: Any) -> "QueryBuilder":
         self._apply_terms(*terms)
         self._replace = False
 
+    def insert_dict(self, data: Dict[str, Any]) -> "QueryBuilder":
+        if self._columns:
+            raise QueryException("Cannot mix use of columns() and insert_dict()")
+
+        cols = data.keys()
+        builder = self.columns(*cols).insert(*data.values())
+        builder._using_insert_dict = True
+        return builder
+
     @builder
     def replace(self, *terms: Any) -> "QueryBuilder":
         self._apply_terms(*terms)
diff --git a/pypika/tests/test_inserts.py b/pypika/tests/test_inserts.py
index f86efd7a..ba180978 100644
--- a/pypika/tests/test_inserts.py
+++ b/pypika/tests/test_inserts.py
@@ -17,6 +17,7 @@
 )
 from pypika.terms import Values
 from pypika.utils import QueryException
+from datetime import datetime
 
 __author__ = "Timothy Heys"
 __email__ = "theys@kayak.com"
@@ -169,6 +170,33 @@ def test_insert_with_statement(self):
         )
 
 
+class InsertIntoWithDict(unittest.TestCase):
+    table_abc = Table("abc")
+
+    def test_inserting_simple_dictionary(self):
+        q = Query.into(self.table_abc).insert_dict({"c1": "value", "c2": 1})
+        self.assertEqual("INSERT INTO \"abc\" (\"c1\",\"c2\") VALUES ('value',1)", str(q))
+
+    def test_inserting_dictionary_goes_through_value_quoting_logic(self):
+        q = Query.into(self.table_abc).insert_dict({"num": 1, "timestamp": datetime(2023, 4, 18)})
+        self.assertEqual("INSERT INTO \"abc\" (\"num\",\"timestamp\") VALUES (1,'2023-04-18T00:00:00')", str(q))
+
+    def test_inserting_dictionary_produces_builder(self):
+        q = Query.into(self.table_abc).insert_dict({"num": 1, "timestamp": datetime(2023, 4, 18)})
+        q = q.insert(2, datetime(2023, 4, 19))
+        self.assertEqual(
+            "INSERT INTO \"abc\" (\"num\",\"timestamp\") VALUES (1,'2023-04-18T00:00:00'),(2,'2023-04-19T00:00:00')",
+            str(q),
+        )
+
+    def test_columns_is_not_allowed_with_insert_dict_even_with_matching_columns(self):
+        with self.assertRaisesRegex(QueryException, "Cannot mix use of columns.*and insert_dict"):
+            Query.into(self.table_abc).columns("num", "key").insert_dict({"num": 1, "key": "foo"})
+
+        with self.assertRaisesRegex(QueryException, "Cannot mix use of columns.*and insert_dict"):
+            Query.into(self.table_abc).insert_dict({"num": 1, "key": "foo"}).columns("num", "key")
+
+
 class PostgresInsertIntoOnConflictTests(unittest.TestCase):
     table_abc = Table("abc")