@@ -28,3 +28,28 @@ 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, six.string_types) 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)
@@ -3,8 +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 widgets
from django.db.models import Q
from django.db.utils import ProgrammingError
@@ -200,3 +203,29 @@ 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
This will allow us to store color codes cleanly in the database. Signed-off-by: Stephen Finucane <stephen@that.guru> --- v2: - Change input type of widget to 'color' --- patchwork/fields.py | 25 +++++++++++++++++++++++++ patchwork/forms.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+)