-
Jonathan Seguin authoredJonathan Seguin authored
forms.py 9.57 KiB
import logging
from crispy_forms.bootstrap import Tab, TabHolder
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout
from django import forms
from django.contrib.auth.models import User
from django.contrib.postgres.forms import HStoreField
from django.urls import resolve
from django.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _
from .models import (Alert, AppSettings, DataFile, DataSet, Institution, Lab,
Profile, ShareGroup)
logger = logging.getLogger('debug')
class BaseNestedFormSet(forms.BaseFormSet):
def is_valid(self):
result = super().is_valid()
if self.is_bound:
for form in self.forms:
if hasattr(form, 'nested'):
result = result and form.nested.is_valid()
return result
class BaseInlineNestedFormSet(forms.BaseInlineFormSet):
def is_valid(self):
result = super().is_valid()
if self.is_bound:
for form in self.forms:
if hasattr(form, 'nested'):
result = result and form.nested.is_valid()
return result
def save(self, commit=True):
result = super().save(commit=commit)
for form in self.forms:
if hasattr(form, 'nested'):
if not self._should_delete_form(form):
form.nested.save(commit=commit)
return result
class AlertForm(forms.ModelForm):
class Meta:
model = Alert
fields = ['id', 'message_en', 'message_fr', 'start', 'end']
labels = {
'message_en': _('Message (English)'),
'message_fr': _('Message (French)'),
'start': _('Start'),
'end': _('End')
}
widgets = {
'message_en': forms.Textarea(attrs={'rows': 3}),
'message_fr': forms.Textarea(attrs={'rows': 3}),
}
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance.pk and self.instance.profile.accountname:
self.fields['first_name'].disabled = True
self.fields['last_name'].disabled = True
self.fields['email'].disabled = True
else:
self.fields['first_name'].required = True
self.fields['last_name'].required = True
self.fields['email'].required = True
class LDAPUserForm(forms.Form):
accountname = forms.CharField(max_length=32, required=True, label=_('LDAP ID'))
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
exclude = ('user', 'accountname')
widgets = {'labs': forms.CheckboxSelectMultiple()}
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
exclude = ('user',)
widgets = {'labs': forms.CheckboxSelectMultiple()}
labels = {
'accountname': _('LDAP ID')
}
field_order = ['accountname']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if hasattr(self.instance, 'user') and self.instance.accountname:
self.fields['labs'].widget = forms.CheckboxSelectMultiple(attrs={'disabled': 'disabled'})
self.fields['accountname'].widget.attrs['readonly'] = True
class InstitutionForm(forms.ModelForm):
class Meta:
model = Institution
fields = ('__all__')
class DataFileForm(forms.ModelForm):
class Meta:
model = DataFile
fields = ('filename', 'annotations', 'lab')
help_texts = {'annotations': _('Pro Tip: You can also drop a tab separated value file onto this field')}
def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['lab'].choices = [('', '----------')]
if request.user.is_staff:
self.fields['lab'].choices += [(lab.id, lab.name) for lab in Lab.objects.all()]
else:
self.fields['lab'].choices += [(lab.id, lab.name) for lab in request.user.profile.labs.all()]
class BasicDataFileForm(forms.ModelForm):
class Meta:
model = DataFile
fields = ('file',)
class DataFileServletUploadForm(forms.ModelForm):
dataset = forms.ModelChoiceField(required=False, label=_('Attach uploaded files to this dataset:'), queryset=DataSet.objects.all())
as_user = forms.ModelChoiceField(required=False, label=_('Upload as user:'), queryset=Profile.objects.all())
class Meta:
model = DataFile
fields = ('file', 'annotations', 'lab')
def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['lab'].choices = [('', '----------')]
if request.user.is_staff:
self.fields['lab'].choices += [(lab.id, lab.name) for lab in Lab.objects.all()]
else:
self.fields['lab'].choices += [(lab.id, lab.name) for lab in request.user.profile.labs.all()]
if not request.user.is_staff:
self.fields['dataset'].queryset = DataSet.objects.accessible_to_profile(request.user.profile).all()
class DataFileAnnotationForm(forms.Form):
dropzone_files = forms.CharField(required=False, widget=forms.HiddenInput)
annotations = HStoreField(required=False, label=_('Attach these annotations with the uploaded files:'), help_text=_('Pro Tip: You can also drop a tab separated value file onto this field'))
lab = forms.ChoiceField(required=False, label=_('Attach uploaded files to this lab:'))
def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['lab'].choices = [('', '----------')]
if request.user.is_staff:
self.fields['lab'].choices += [(lab.id, lab.name) for lab in Lab.objects.all()]
else:
self.fields['lab'].choices += [(lab.id, lab.name) for lab in request.user.profile.labs.all()]
class BatchAddDataFileAnnotationForm(forms.Form):
datafiles = forms.MultipleChoiceField(required=True, widget=forms.HiddenInput)
annotations = HStoreField(required=True, label=_('Add/Update the following annotations for the selected files'), help_text=_('Pro Tip: You can also drop a tab separated value file onto this field'))
class BatchRemoveDataFileAnnotationForm(forms.Form):
datafiles = forms.MultipleChoiceField(required=True, widget=forms.HiddenInput)
annotations = forms.MultipleChoiceField(required=True, label=_('Remove the following annotations from the selected files'))
class DataSetForm(forms.ModelForm):
class Meta:
model = DataSet
fields = ('name', 'share_profiles', 'share_labs', 'share_groups', 'files')
labels = {
'name': _('Name'),
'share_profiles': _('Share with these users'),
'share_labs': _('Share with these labs'),
'share_groups': _('Share with these groups'),
'files': _('Files')
}
class DataSetDisplayFieldsForm(forms.ModelForm):
options = forms.MultipleChoiceField(
required=False, widget=forms.CheckboxSelectMultiple,
label=_('Choose the fields you would like to use when displaying the DataSet details'),
help_text=_('Pro Tip: The order in which you click the options will determine their display order')
)
class Meta:
model = DataSet
fields = ('display_fields',)
labels = {'display_fields': _('Manually rearrange the field names to alter their display order')}
help_texts = {'display_fields': _('Pro Tip: Field names should be comma separated')}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
choice_fields = set()
for f in self.instance.files.all():
if f.annotations:
choice_fields.update([k for k in f.annotations.keys()])
self.fields['options'].choices = [
('name', 'name'), ('size', 'size'),
('upload_timestamp', 'upload_timestamp'), ('uploaded_by', 'uploaded_by')
] + [(f, f) for f in choice_fields]
if self.instance.display_fields:
self.fields['options'].initial = [df for df in self.instance.display_fields['fields'].split(', ')]
self.helper = FormHelper(self)
self.helper.form_tag = False
self.helper.use_custom_control = True
self.helper.layout = Layout(
TabHolder(
Tab(
ugettext('Display Options'),
'options'
),
Tab(
ugettext('Manual override'),
'display_fields',
)
)
)
class LabForm(forms.ModelForm):
class Meta:
model = Lab
fields = ('__all__')
class ShareGroupForm(forms.ModelForm):
class Meta:
model = ShareGroup
fields = ('name', 'profiles')
class LabSelectionForm(forms.Form):
lab = forms.ChoiceField(required=True)
redirect_to = forms.CharField(max_length=256, required=True, widget=forms.HiddenInput)
def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs)
if request.user.is_authenticated:
self.fields['lab'].choices = [(lab.id, lab.name) for lab in request.user.profile.labs.all()]
self.fields['lab'].initial = request.session.get('active_lab_id')
self.fields['redirect_to'].initial = resolve(request.path_info).url_name
self.helper = FormHelper()
self.helper.form_show_labels = False
class AppSettingsForm(forms.ModelForm):
class Meta:
model = AppSettings
fields = ('__all__')