216 lines
7.2 KiB
Python
216 lines
7.2 KiB
Python
from __future__ import unicode_literals
|
|
|
|
import os
|
|
|
|
from django import forms
|
|
from django.conf import settings
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
from django.db import models
|
|
from django.utils.module_loading import import_string
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from .classes import Package
|
|
from .models import UserLocaleProfile
|
|
from .utils import resolve_attribute
|
|
from .widgets import DisableableSelectWidget, PlainWidget, TextAreaDiv
|
|
|
|
|
|
class ChoiceForm(forms.Form):
|
|
"""
|
|
Form to be used in side by side templates used to add or remove
|
|
items from a many to many field
|
|
"""
|
|
def __init__(self, *args, **kwargs):
|
|
choices = kwargs.pop('choices', [])
|
|
label = kwargs.pop('label', _('Selection'))
|
|
help_text = kwargs.pop('help_text', None)
|
|
disabled_choices = kwargs.pop('disabled_choices', ())
|
|
super(ChoiceForm, self).__init__(*args, **kwargs)
|
|
self.fields['selection'].choices = choices
|
|
self.fields['selection'].label = label
|
|
self.fields['selection'].help_text = help_text
|
|
self.fields['selection'].widget.disabled_choices = disabled_choices
|
|
self.fields['selection'].widget.attrs.update(
|
|
{
|
|
'class': 'full-height', 'data-height-difference': '450'
|
|
}
|
|
)
|
|
|
|
selection = forms.MultipleChoiceField(widget=DisableableSelectWidget())
|
|
|
|
|
|
class DetailForm(forms.ModelForm):
|
|
def __init__(self, *args, **kwargs):
|
|
self.extra_fields = kwargs.pop('extra_fields', ())
|
|
super(DetailForm, self).__init__(*args, **kwargs)
|
|
|
|
for extra_field in self.extra_fields:
|
|
result = resolve_attribute(obj=self.instance, attribute=extra_field['field'])
|
|
label = 'label' in extra_field and extra_field['label'] or None
|
|
# TODO: Add others result types <=> Field types
|
|
if isinstance(result, models.query.QuerySet):
|
|
self.fields[extra_field['field']] = \
|
|
forms.ModelMultipleChoiceField(
|
|
queryset=result, label=label)
|
|
else:
|
|
self.fields[extra_field['field']] = forms.CharField(
|
|
label=extra_field['label'],
|
|
initial=resolve_attribute(
|
|
obj=self.instance,
|
|
attribute=extra_field['field']
|
|
),
|
|
widget=extra_field.get('widget', PlainWidget)
|
|
)
|
|
|
|
for field_name, field in self.fields.items():
|
|
self.fields[field_name].widget.attrs.update(
|
|
{'readonly': 'readonly'}
|
|
)
|
|
|
|
|
|
class DynamicFormMixin(object):
|
|
def __init__(self, *args, **kwargs):
|
|
self.schema = kwargs.pop('schema')
|
|
super(DynamicFormMixin, self).__init__(*args, **kwargs)
|
|
|
|
widgets = self.schema.get('widgets', {})
|
|
field_order = self.schema.get(
|
|
'field_order', self.schema['fields'].keys()
|
|
)
|
|
|
|
for field_name in field_order:
|
|
field_data = self.schema['fields'][field_name]
|
|
field_class = import_string(field_data['class'])
|
|
kwargs = {
|
|
'label': field_data['label'],
|
|
'required': field_data.get('required', True),
|
|
'initial': field_data.get('default', None),
|
|
'help_text': field_data.get('help_text'),
|
|
}
|
|
if widgets and field_name in widgets:
|
|
widget = widgets[field_name]
|
|
kwargs['widget'] = import_string(
|
|
widget['class']
|
|
)(**widget.get('kwargs', {}))
|
|
|
|
kwargs.update(field_data.get('kwargs', {}))
|
|
self.fields[field_name] = field_class(**kwargs)
|
|
|
|
|
|
class DynamicForm(DynamicFormMixin, forms.Form):
|
|
pass
|
|
|
|
|
|
class DynamicModelForm(DynamicFormMixin, forms.ModelForm):
|
|
pass
|
|
|
|
|
|
class FileDisplayForm(forms.Form):
|
|
DIRECTORY = None
|
|
FILENAME = None
|
|
|
|
text = forms.CharField(
|
|
label='',
|
|
widget=TextAreaDiv(
|
|
attrs={
|
|
'class': 'full-height scrollable',
|
|
'data-height-difference': 270
|
|
}
|
|
)
|
|
)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(FileDisplayForm, self).__init__(*args, **kwargs)
|
|
if self.DIRECTORY or self.FILENAME:
|
|
file_path = os.path.join(
|
|
settings.BASE_DIR, os.sep.join(self.DIRECTORY), self.FILENAME
|
|
)
|
|
with open(file_path) as file_object:
|
|
self.fields['text'].initial = file_object.read()
|
|
|
|
|
|
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):
|
|
field_name = kwargs.pop('field_name', None)
|
|
label = kwargs.pop('label', None)
|
|
help_text = kwargs.pop('help_text', None)
|
|
permission = kwargs.pop('permission', None)
|
|
queryset = kwargs.pop('queryset', None)
|
|
|
|
if queryset is None:
|
|
model = kwargs.pop('model', None)
|
|
if not model:
|
|
raise ImproperlyConfigured(
|
|
'Must provide a queryset or a model.'
|
|
)
|
|
|
|
queryset = model.objects.all()
|
|
|
|
user = kwargs.pop('user', None)
|
|
widget_class = kwargs.pop('widget_class', None)
|
|
widget_attributes = kwargs.pop('widget_attributes', {'size': '10'})
|
|
|
|
if not widget_class:
|
|
if kwargs.pop('allow_multiple', False):
|
|
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
|
|
|
|
super(FilteredSelectionForm, self).__init__(*args, **kwargs)
|
|
|
|
if permission:
|
|
queryset = AccessControlList.objects.filter_by_access(
|
|
permission=permission, queryset=queryset, user=user
|
|
)
|
|
|
|
self.fields[field_name] = field_class(
|
|
help_text=help_text, label=label,
|
|
queryset=queryset, required=True,
|
|
widget=widget_class(attrs=widget_attributes), **extra_kwargs
|
|
)
|
|
|
|
|
|
class LicenseForm(FileDisplayForm):
|
|
DIRECTORY = ()
|
|
FILENAME = 'LICENSE'
|
|
|
|
|
|
class LocaleProfileForm(forms.ModelForm):
|
|
class Meta:
|
|
fields = ('language', 'timezone')
|
|
model = UserLocaleProfile
|
|
widgets = {
|
|
'language': forms.Select(
|
|
attrs={
|
|
'class': 'select2'
|
|
}
|
|
),
|
|
'timezone': forms.Select(
|
|
attrs={
|
|
'class': 'select2'
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
class LocaleProfileForm_view(DetailForm):
|
|
class Meta:
|
|
fields = ('language', 'timezone')
|
|
model = UserLocaleProfile
|
|
|
|
|
|
class PackagesLicensesForm(FileDisplayForm):
|
|
def __init__(self, *args, **kwargs):
|
|
super(PackagesLicensesForm, self).__init__(*args, **kwargs)
|
|
self.fields['text'].initial = '\n\n'.join(
|
|
['{}\n{}'.format(package.label, package.license_text) for package in Package.get_all()]
|
|
)
|