Add FilteredSelectionForm class
Use FilteredSelectionForm to reduce boilerplate code for TagMultipleSelectionForm. Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -55,6 +55,8 @@
|
||||
* Reduce form boilerplate code with new FormOptions class.
|
||||
* Use FormOptions for the DetailForm class.
|
||||
* DetailForm now support help text on extra fields.
|
||||
* Add FilteredSelectionForm class.
|
||||
* Use FilteredSelectionForm for TagMultipleSelectionForm.
|
||||
|
||||
3.1.11 (2019-04-XX)
|
||||
===================
|
||||
|
||||
@@ -79,6 +79,8 @@ Other changes
|
||||
* Reduce form boilerplate code with new FormOptions class.
|
||||
* Use FormOptions for the DetailForm class.
|
||||
* DetailForm now support help text on extra fields.
|
||||
* Add FilteredSelectionForm class.
|
||||
* Use FilteredSelectionForm for TagMultipleSelectionForm.
|
||||
|
||||
Removals
|
||||
--------
|
||||
|
||||
@@ -6,11 +6,13 @@ from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib.admin.utils import label_for_field
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core.exceptions import FieldDoesNotExist
|
||||
from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
|
||||
from django.db import models
|
||||
from django.utils.module_loading import import_string
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from mayan.apps.acls.models import AccessControlList
|
||||
|
||||
from .classes import Package
|
||||
from .models import UserLocaleProfile
|
||||
from .utils import introspect_attribute, resolve_attribute
|
||||
@@ -198,6 +200,74 @@ class FileDisplayForm(forms.Form):
|
||||
self.fields['text'].initial = file_object.read()
|
||||
|
||||
|
||||
class FilteredSelectionFormOptions(FormOptions):
|
||||
# Dictionary list of option names and default values
|
||||
option_definitions = {
|
||||
'allow_multiple': False,
|
||||
'field_name': None,
|
||||
'help_text': None,
|
||||
'label': None,
|
||||
'model': None,
|
||||
'permission': None,
|
||||
'queryset': None,
|
||||
'required': True,
|
||||
'user': None,
|
||||
'widget_class': None,
|
||||
'widget_attributes': {'size': '10'},
|
||||
}
|
||||
|
||||
|
||||
class FilteredSelectionForm(forms.Form):
|
||||
"""
|
||||
Form to select the from a list of choice filtered by access. Can be
|
||||
configure to allow single or multiple selection.
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
opts = FilteredSelectionFormOptions(
|
||||
form=self, kwargs=kwargs, options=getattr(self, 'Meta', None)
|
||||
)
|
||||
|
||||
if opts.queryset is None:
|
||||
if not opts.model:
|
||||
raise ImproperlyConfigured(
|
||||
'{} requires a queryset or a model to be specified as '
|
||||
'a meta option or passed during initialization.'.format(
|
||||
self.__class__.__name__
|
||||
)
|
||||
)
|
||||
|
||||
queryset = opts.model.objects.all()
|
||||
else:
|
||||
queryset = opts.queryset
|
||||
|
||||
if opts.allow_multiple:
|
||||
extra_kwargs = {}
|
||||
field_class = forms.ModelMultipleChoiceField
|
||||
widget_class = forms.widgets.SelectMultiple
|
||||
else:
|
||||
extra_kwargs = {'empty_label': None}
|
||||
field_class = forms.ModelChoiceField
|
||||
widget_class = forms.widgets.Select
|
||||
|
||||
if opts.widget_class:
|
||||
widget_class = opts.widget_class
|
||||
|
||||
if opts.permission:
|
||||
queryset = AccessControlList.objects.filter_by_access(
|
||||
permission=opts.permission, queryset=queryset,
|
||||
user=opts.user
|
||||
)
|
||||
|
||||
super(FilteredSelectionForm, self).__init__(*args, **kwargs)
|
||||
|
||||
self.fields[opts.field_name] = field_class(
|
||||
help_text=opts.help_text, label=opts.label,
|
||||
queryset=queryset, required=opts.required,
|
||||
widget=widget_class(attrs=opts.widget_attributes),
|
||||
**extra_kwargs
|
||||
)
|
||||
|
||||
|
||||
class LicenseForm(FileDisplayForm):
|
||||
DIRECTORY = ()
|
||||
FILENAME = 'LICENSE'
|
||||
|
||||
@@ -1,40 +1,20 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from mayan.apps.acls.models import AccessControlList
|
||||
from mayan.apps.common.forms import FilteredSelectionForm
|
||||
|
||||
from .models import Tag
|
||||
from .permissions import permission_tag_view
|
||||
from .widgets import TagFormWidget
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TagMultipleSelectionForm(forms.Form):
|
||||
class TagMultipleSelectionForm(FilteredSelectionForm):
|
||||
class Media:
|
||||
js = ('tags/js/tags_form.js',)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
help_text = kwargs.pop('help_text', None)
|
||||
permission = kwargs.pop('permission', permission_tag_view)
|
||||
queryset = kwargs.pop('queryset', Tag.objects.all())
|
||||
user = kwargs.pop('user', None)
|
||||
|
||||
logger.debug('user: %s', user)
|
||||
super(TagMultipleSelectionForm, self).__init__(*args, **kwargs)
|
||||
|
||||
queryset = AccessControlList.objects.filter_by_access(
|
||||
permission=permission, queryset=queryset, user=user
|
||||
)
|
||||
|
||||
self.fields['tags'] = forms.ModelMultipleChoiceField(
|
||||
label=_('Tags'), help_text=help_text,
|
||||
queryset=queryset, required=False,
|
||||
widget=TagFormWidget(
|
||||
attrs={'class': 'select2-tags'}, queryset=queryset
|
||||
)
|
||||
)
|
||||
class Meta:
|
||||
allow_multiple = True
|
||||
field_name = 'tags'
|
||||
label = _('Tags')
|
||||
required = False
|
||||
widget_class = TagFormWidget
|
||||
widget_attributes = {'class': 'select2-tags'}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
{% include 'django/forms/widgets/select_option.html' %}
|
||||
|
||||
@@ -69,6 +69,7 @@ class TagAttachActionView(MultipleObjectFormActionView):
|
||||
result = {
|
||||
'help_text': _('Tags to be attached.'),
|
||||
'permission': permission_tag_attach,
|
||||
'queryset': Tag.objects.all(),
|
||||
'user': self.request.user
|
||||
}
|
||||
|
||||
@@ -311,6 +312,7 @@ class TagRemoveActionView(MultipleObjectFormActionView):
|
||||
result = {
|
||||
'help_text': _('Tags to be removed.'),
|
||||
'permission': permission_tag_remove,
|
||||
'queryset': Tag.objects.all(),
|
||||
'user': self.request.user
|
||||
}
|
||||
|
||||
|
||||
@@ -10,19 +10,17 @@ from .permissions import permission_tag_view
|
||||
|
||||
|
||||
class TagFormWidget(forms.SelectMultiple):
|
||||
option_template_name = 'tags/forms/widgets/tag_select_option.html'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.queryset = kwargs.pop('queryset')
|
||||
return super(TagFormWidget, self).__init__(*args, **kwargs)
|
||||
|
||||
def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
|
||||
result = super(TagFormWidget, self).create_option(
|
||||
name=name, value=value, label='{}'.format(conditional_escape(label)),
|
||||
selected=selected, index=index, subindex=subindex, attrs=attrs
|
||||
attrs=attrs, index=index,
|
||||
label='{}'.format(conditional_escape(label)), name=name,
|
||||
selected=selected, subindex=subindex, value=value
|
||||
)
|
||||
|
||||
result['attrs']['data-color'] = self.queryset.get(pk=value).color
|
||||
result['attrs']['data-color'] = self.choices.queryset.get(pk=value).color
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from mayan.apps.sources.wizards import WizardStep
|
||||
|
||||
from .forms import TagMultipleSelectionForm
|
||||
from .models import Tag
|
||||
from .permissions import permission_tag_attach
|
||||
|
||||
|
||||
class WizardStepTags(WizardStep):
|
||||
@@ -26,6 +28,8 @@ class WizardStepTags(WizardStep):
|
||||
def get_form_kwargs(self, wizard):
|
||||
return {
|
||||
'help_text': _('Tags to be attached.'),
|
||||
'model': Tag,
|
||||
'permission': permission_tag_attach,
|
||||
'user': wizard.request.user
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ class AttachTagAction(WorkflowAction):
|
||||
'tags': {
|
||||
'class': 'tags.widgets.TagFormWidget', 'kwargs': {
|
||||
'attrs': {'class': 'select2-tags'},
|
||||
'queryset': Tag.objects.none()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,7 +42,6 @@ class AttachTagAction(WorkflowAction):
|
||||
)
|
||||
|
||||
self.fields['tags']['kwargs']['queryset'] = queryset
|
||||
self.widgets['tags']['kwargs']['queryset'] = queryset
|
||||
|
||||
return {
|
||||
'fields': self.fields,
|
||||
|
||||
Reference in New Issue
Block a user