Skip to content

Commit bacb840

Browse files
stephenfinfstachura
authored andcommitted
fields: Add ColorField
This will allow us to store color codes cleanly in the database.
1 parent bd0d6ae commit bacb840

2 files changed

Lines changed: 52 additions & 1 deletion

File tree

‎patchwork/fields.py‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,27 @@ def from_db_value(self, value, *args, **kwargs):
2727

2828
def db_type(self, connection=None):
2929
return 'char(%d)' % self.n_bytes
30+
31+
32+
class ColorField(models.Field):
33+
description = 'Hex color code'
34+
35+
def get_internal_type(self):
36+
return 'PositiveIntegerField'
37+
38+
def to_python(self, value):
39+
if isinstance(value, str) or value is None:
40+
return value
41+
return '#%06x' % value
42+
43+
def from_db_value(self, value, *args, **kwargs):
44+
return self.to_python(value)
45+
46+
def get_prep_value(self, value):
47+
return int(value.lstrip('#'), 16)
48+
49+
def formfield(self, *args, **kwargs):
50+
from patchwork import forms # noqa
51+
52+
kwargs['form_class'] = forms.ColorField
53+
return super(ColorField, self).formfield(*args, **kwargs)

‎patchwork/forms.py‎

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
#
44
# SPDX-License-Identifier: GPL-2.0-or-later
55

6+
import re
7+
68
from django.contrib.auth.models import User
79
from django import forms
8-
from django.forms import renderers
10+
from django.forms import widgets, renderers
911
from django.db.models import Q
1012
from django.db.utils import ProgrammingError
1113
from django.template.backends import django as django_template_backend
@@ -253,3 +255,28 @@ def save(self, instance, commit=True):
253255
if commit:
254256
instance.save()
255257
return instance
258+
259+
260+
class ColorInput(widgets.Input):
261+
input_type = 'color'
262+
263+
264+
class ColorField(forms.CharField):
265+
widget = ColorInput
266+
default_error_messages = {
267+
'invalid': 'Enter a valid colour value: e.g. "#ff0022"',
268+
}
269+
270+
def clean(self, value):
271+
if not re.match('^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$', value):
272+
raise forms.ValidationError(self.error_messages['invalid'])
273+
274+
value = int(value.lstrip('#'), 16)
275+
super(ColorField, self).clean(value)
276+
277+
return value
278+
279+
def widget_attrs(self, widget):
280+
attrs = super().widget_attrs(widget)
281+
attrs['maxlength'] = 7
282+
return attrs

0 commit comments

Comments
 (0)