diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 1ca1b97a543e2b9db54a5a6238799d4dedf38bb2..8a7eb12b53641991e8aa544b27a5a16befa05e29 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -16,6 +16,7 @@ Added
 * Field types can now provide values for arbitrary alternative DB fields
 * Virtual fields can be generated from literal fields using Django templates
 * Fields for Group.parent_groups and Person.member_of
+* Quote character can now be configured in template
 
 Fixed
 ~~~~~
diff --git a/aleksis/apps/csv_import/migrations/0008_configurable_quotechar.py b/aleksis/apps/csv_import/migrations/0008_configurable_quotechar.py
new file mode 100644
index 0000000000000000000000000000000000000000..559096157ab0f8cfa935ce9b49733a817e3e28f5
--- /dev/null
+++ b/aleksis/apps/csv_import/migrations/0008_configurable_quotechar.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.2.11 on 2022-01-29 22:44
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('csv_import', '0007_virtual_template_field'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='importtemplate',
+            name='quotechar',
+            field=models.CharField(default='"', max_length=255, verbose_name='CSV quote character'),
+        ),
+    ]
diff --git a/aleksis/apps/csv_import/models.py b/aleksis/apps/csv_import/models.py
index 510c889239aaa69059b14f1be4498d8d11a8de86..1aa4ff46299a8cd0f39dc60850f8d888f6735c04 100644
--- a/aleksis/apps/csv_import/models.py
+++ b/aleksis/apps/csv_import/models.py
@@ -36,6 +36,11 @@ class ImportTemplate(ExtensibleModel):
         verbose_name=_("CSV separator"),
         help_text=_("For whitespace use \\\\s+, for tab \\\\t"),
     )
+    quotechar = models.CharField(
+        max_length=255,
+        default='"',
+        verbose_name=_("CSV quote character"),
+    )
 
     group = models.ForeignKey(
         Group,
@@ -62,6 +67,10 @@ class ImportTemplate(ExtensibleModel):
     def parsed_separator(self):
         return codecs.escape_decode(bytes(self.separator, "utf-8"))[0].decode("utf-8")
 
+    @property
+    def parsed_quotechar(self):
+        return codecs.escape_decode(bytes(self.quotechar, "utf-8"))[0].decode("utf-8")
+
     def save(self, *args, **kwargs):
         if not self.content_type.model == "person":
             self.group = None
diff --git a/aleksis/apps/csv_import/util/process.py b/aleksis/apps/csv_import/util/process.py
index b758f3a0d0e09c58c8585768f79e1e0a2fed337f..7619f7b0296f131d9d1965c9160a8dc55bc5f84b 100644
--- a/aleksis/apps/csv_import/util/process.py
+++ b/aleksis/apps/csv_import/util/process.py
@@ -106,7 +106,7 @@ def import_csv(
                         usecols=lambda k: not k.startswith("_"),
                         keep_default_na=False,
                         converters=converters,
-                        quotechar='"',
+                        quotechar=template.parsed_quotechar,
                         encoding=encoding,
                         true_values=TRUE_VALUES,
                         false_values=FALSE_VALUES,