From: Stephen Finucane <[email protected]>

This will allow us to store color codes cleanly in the database.

Signed-off-by: Franciszek Stachura <[email protected]>
---
 patchwork/fields.py | 24 ++++++++++++++++++++++++
 patchwork/forms.py  | 29 ++++++++++++++++++++++++++++-
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/patchwork/fields.py b/patchwork/fields.py
index 5cdebcd5..dc5f92ba 100644
--- a/patchwork/fields.py
+++ b/patchwork/fields.py
@@ -27,3 +27,27 @@ class HashField(models.CharField):
 
     def db_type(self, connection=None):
         return 'char(%d)' % self.n_bytes
+
+
+class ColorField(models.Field):
+    description = 'Hex color code'
+
+    def get_internal_type(self):
+        return 'PositiveIntegerField'
+
+    def to_python(self, value):
+        if isinstance(value, str) or value is None:
+            return value
+        return '#%06x' % value
+
+    def from_db_value(self, value, *args, **kwargs):
+        return self.to_python(value)
+
+    def get_prep_value(self, value):
+        return int(value.lstrip('#'), 16)
+
+    def formfield(self, *args, **kwargs):
+        from patchwork import forms  # noqa
+
+        kwargs['form_class'] = forms.ColorField
+        return super(ColorField, self).formfield(*args, **kwargs)
diff --git a/patchwork/forms.py b/patchwork/forms.py
index efedfa97..1e62368a 100644
--- a/patchwork/forms.py
+++ b/patchwork/forms.py
@@ -3,9 +3,11 @@
 #
 # SPDX-License-Identifier: GPL-2.0-or-later
 
+import re
+
 from django.contrib.auth.models import User
 from django import forms
-from django.forms import renderers
+from django.forms import widgets, renderers
 from django.db.models import Q
 from django.db.utils import ProgrammingError
 from django.template.backends import django as django_template_backend
@@ -253,3 +255,28 @@ class MultiplePatchForm(forms.Form):
         if commit:
             instance.save()
         return instance
+
+
+class ColorInput(widgets.Input):
+    input_type = 'color'
+
+
+class ColorField(forms.CharField):
+    widget = ColorInput
+    default_error_messages = {
+        'invalid': 'Enter a valid colour value: e.g. "#ff0022"',
+    }
+
+    def clean(self, value):
+        if not re.match('^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$', value):
+            raise forms.ValidationError(self.error_messages['invalid'])
+
+        value = int(value.lstrip('#'), 16)
+        super(ColorField, self).clean(value)
+
+        return value
+
+    def widget_attrs(self, widget):
+        attrs = super().widget_attrs(widget)
+        attrs['maxlength'] = 7
+        return attrs
-- 
2.55.0

_______________________________________________
Patchwork mailing list
[email protected]
https://lists.ozlabs.org/listinfo/patchwork

Reply via email to