stages/identification: replace buggy FilteredSelectMultiple with ArrayFieldSelectMultiple

This commit is contained in:
Jens Langhammer 2020-09-30 23:55:23 +02:00
parent 516455f482
commit 8f585eca70
4 changed files with 41 additions and 7 deletions

View File

@ -1,9 +1,35 @@
"""YAML fields""" """Additional fields"""
import yaml import yaml
from django import forms from django import forms
from django.utils.datastructures import MultiValueDict
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
class ArrayFieldSelectMultiple(forms.SelectMultiple):
"""This is a Form Widget for use with a Postgres ArrayField. It implements
a multi-select interface that can be given a set of `choices`.
You can provide a `delimiter` keyword argument to specify the delimeter used.
https://gist.github.com/stephane/00e73c0002de52b1c601"""
def __init__(self, *args, **kwargs):
# Accept a `delimiter` argument, and grab it (defaulting to a comma)
self.delimiter = kwargs.pop("delimiter", ",")
super().__init__(*args, **kwargs)
def value_from_datadict(self, data, files, name):
if isinstance(data, MultiValueDict):
# Normally, we'd want a list here, which is what we get from the
# SelectMultiple superclass, but the SimpleArrayField expects to
# get a delimited string, so we're doing a little extra work.
return self.delimiter.join(data.getlist(name))
return data.get(name)
def get_context(self, name, value, attrs):
return super().get_context(name, value.split(self.delimiter), attrs)
class CodeMirrorWidget(forms.Textarea): class CodeMirrorWidget(forms.Textarea):
"""Custom Textarea-based Widget that triggers a CodeMirror editor""" """Custom Textarea-based Widget that triggers a CodeMirror editor"""

View File

@ -1,10 +1,10 @@
"""passbook flows identification forms""" """passbook flows identification forms"""
from django import forms from django import forms
from django.contrib.admin.widgets import FilteredSelectMultiple
from django.core.validators import validate_email from django.core.validators import validate_email
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from structlog import get_logger from structlog import get_logger
from passbook.admin.fields import ArrayFieldSelectMultiple
from passbook.flows.models import Flow, FlowDesignation from passbook.flows.models import Flow, FlowDesignation
from passbook.lib.utils.ui import human_list from passbook.lib.utils.ui import human_list
from passbook.stages.identification.models import IdentificationStage, UserFields from passbook.stages.identification.models import IdentificationStage, UserFields
@ -37,9 +37,7 @@ class IdentificationStageForm(forms.ModelForm):
] ]
widgets = { widgets = {
"name": forms.TextInput(), "name": forms.TextInput(),
"user_fields": FilteredSelectMultiple( "user_fields": ArrayFieldSelectMultiple(choices=UserFields.choices),
_("fields"), False, choices=UserFields.choices
),
} }

View File

@ -30,7 +30,12 @@ class IdentificationStage(Stage):
user_fields = ArrayField( user_fields = ArrayField(
models.CharField(max_length=100, choices=UserFields.choices), models.CharField(max_length=100, choices=UserFields.choices),
help_text=_("Fields of the user object to match against."), help_text=_(
(
"Fields of the user object to match against. "
"(Hold shift to select multiple options)"
)
),
) )
template = models.TextField(choices=Templates.choices) template = models.TextField(choices=Templates.choices)

View File

@ -7342,7 +7342,8 @@ definitions:
type: string type: string
minLength: 1 minLength: 1
user_fields: user_fields:
description: Fields of the user object to match against. description: Fields of the user object to match against. (Hold shift to select
multiple options)
type: array type: array
items: items:
title: User fields title: User fields
@ -7350,6 +7351,10 @@ definitions:
enum: enum:
- email - email
- username - username
case_insensitive_matching:
title: Case insensitive matching
description: When enabled, user fields are matched regardless of their casing.
type: boolean
template: template:
title: Template title: Template
type: string type: string