This repository has been archived on 2022-08-01. You can view files and clone it, but cannot push or open issues or pull requests.
DEMOS2/allauthdemo/polls/forms.py

333 lines
13 KiB
Python
Executable file

from django import forms
from django.template.loader import render_to_string
from django.template import Context
from django.core.exceptions import ValidationError
from django.core.validators import EmailValidator
from crispy_forms.helper import FormHelper
from crispy_forms.layout import LayoutObject, Layout, TEMPLATE_PACK, Div, Field, HTML
from crispy_forms.bootstrap import PrependedText, PrependedAppendedText, Accordion, AccordionGroup
from allauthdemo.auth.models import DemoUser
from .models import Event, Poll, PollOption
def is_valid_email(email):
try:
valid_email = EmailValidator()
valid_email(email)
return True
except ValidationError:
return False
# This form has been deprecated
class EventForm(forms.ModelForm):
voters = forms.CharField(label="Voters", required=False, widget=forms.Textarea(attrs={'width':"100%", 'cols' : "80", 'rows': "20", }))
votersTextFile = forms.FileField(required=False)
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.form_show_labels = False
self.helper.layout = Layout(
Accordion(
AccordionGroup('Event Details',
PrependedText('title', 'Title', placeholder="Title of the Event"),
Div(
PrependedAppendedText('start_time', 'Begins', '<span class="glyphicon glyphicon-calendar"></span>', placeholder="dd/mm/yyyy hh:mm"),
css_class="input-group date col-sm-6"
),
Div(
PrependedAppendedText('end_time', 'Ends', '<span class="glyphicon glyphicon-calendar"></span>', placeholder="dd/mm/yyyy hh:mm"),
css_class="input-group date col-sm-6"
)
),
AccordionGroup("Organisers",
HTML("<p>Event creators are automatically made an Organiser. Click and drag the tabs to reorder. Blank fields will be ignored.</p>"),
Formset("organiser_formset",
"polls/create_option.html",
OrganiserFormSetHelper()
),
),
AccordionGroup('Trustees',
HTML("<p>Click and drag the tabs to reorder. Blank fields will be ignored.</p>"),
Formset("trustee_formset",
"polls/create_option.html",
TrusteeFormSetHelper()
),
),
AccordionGroup('Voters',
'voters',
HTML("<p>Comma seperated (.csv) file of valid email addresses</p>"),
'votersTextFile'
),
),
)
super(EventForm, self).__init__(*args, **kwargs)
class Meta:
model = Event
fields = ('title', 'start_time', 'end_time')
widgets = {
'voters': forms.Textarea(attrs={'cols': 80, 'rows': 20})
}
# This form has been deprecated
class EventEditForm(forms.ModelForm):
voters = forms.CharField(label="Voters", required=False, widget=forms.Textarea(attrs={'width':"100%", 'cols' : "80", 'rows': "20", }))
votersTextFile = forms.FileField(required=False)
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.form_show_labels = False
self.helper.layout = Layout(
Accordion(
AccordionGroup('Event Details',
PrependedText('title', 'Title', placeholder="Title of the Event"),
Div(
PrependedAppendedText('start_time', 'Begins', '<span class="glyphicon glyphicon-calendar"></span>', placeholder="dd/mm/yyyy hh:mm"),
css_class="input-group date col-sm-6"
),
Div(
PrependedAppendedText('end_time', 'Ends', '<span class="glyphicon glyphicon-calendar"></span>', placeholder="dd/mm/yyyy hh:mm"),
css_class="input-group date col-sm-6"
)
),
AccordionGroup('Voters',
'voters',
HTML("<p>Comma seperated (.csv) file of valid email addresses</p>"),
'votersTextFile'
),
),
)
super(EventEditForm, self).__init__(*args, **kwargs)
class Meta:
model = Event
fields = ('title', 'start_time', 'end_time')
widgets = {
'voters': forms.Textarea(attrs={'cols': 80, 'rows': 20})
}
class EventSetupForm(forms.Form):
public_key = forms.CharField(max_length=1024, required=True)
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.form_show_labels = False
self.helper.layout = Layout(
Field('public_key', id="public-key")
)
super(EventSetupForm, self).__init__(*args, **kwargs)
class Meta:
fields = ('public_key',)
class PollForm(forms.ModelForm):
question_text = forms.CharField(
max_length = 80,
required = True,
)
def __init__(self, *args, **kwargs):
option_formset = kwargs.pop('option_formset', None)
choices = option_formset.total_form_count() if option_formset else 2
self.helper = FormHelper()
self.helper.form_show_labels = False
self.helper.form_tag = False
self.helper.layout = Layout(
Accordion(
AccordionGroup("Poll Details",
PrependedText('question_text', 'Question', placeholder='The question or title of your poll')
),
AccordionGroup("Poll Options",
HTML("<p>Click and drag the tabs to reorder</p>"),
Formset("option_formset",
"polls/create_option.html",
PollOptionFormSetHelper()
)
)
),
)
super(PollForm, self).__init__(*args, **kwargs)
class Meta:
model = Poll
fields = ('question_text',)
class VoteModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.choice_text
class VoteForm(forms.ModelForm):
cipher_text_c1 = forms.CharField(
max_length = 1024,
required = True,
)
cipher_text_c2 = forms.CharField(
max_length = 1024,
required = True,
)
def __init__(self, *args, **kwargs):
super(VoteForm, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_show_labels = False
self.helper.form_tag = False
self.helper.layout = Layout(
Field('cipher_text_c1', type="hidden"),
Field('cipher_text_c2', type="hidden")
)
class Meta:
model = Poll
fields = ()#'options')
class DecryptionForm(forms.Form):
text = forms.CharField(max_length=1024, required=True)
def __init__(self, *args, **kwargs):
super(DecryptionForm, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_show_labels = False
self.helper.form_tag = False
self.layout = Layout(
PrependedText('text', 'Cipher'),
)
class Meta:
model = Poll
fields = ('enc',)#'options')
class EmailForm(forms.Form):
email = forms.CharField(
max_length = 80,
required = True,
)
def __init__(self, *args, **kwargs):
super(EmailForm, self).__init__(*args, **kwargs)
def clean_email(self):
email = self.cleaned_data['email']
if is_valid_email(email):
return email
raise forms.ValidationError(u'This doesn\'t appear to be a valid email address.')
class OrganiserForm(EmailForm):
def clean_email(self):
email = self.cleaned_data['email']
if is_valid_email(email):
if DemoUser.objects.filter(email=email).exists():
return email
raise forms.ValidationError(u'User "%s" does not exist.' % email)
raise forms.ValidationError(u'This doesn\'t appear to be a valid email address.')
class BaseFormSetHelper(FormHelper):
def __init__(self, *args, **kwargs):
super(BaseFormSetHelper, self).__init__(*args, **kwargs)
self.form_method = 'post'
self.form_show_labels = False
self.form_tag = False
self.layout = Layout()
#Field('organiser_email', placeholder="Option here")
self.render_required_fields = True
class OrganiserFormSetHelper(BaseFormSetHelper):
def __init__(self, *args, **kwargs):
super(OrganiserFormSetHelper, self).__init__(*args, **kwargs)
self.layout = Layout(
Div(
Field('DELETE', css_class='input-small hidden'),
PrependedAppendedText('email', 'Email ', "<span data-toggle='tooltip' title='Delete this Organiser' class='glyphicon glyphicon-trash'></span>", placeholder="Email address of the organiser"),
css_class="formset_object")
)
class DecryptionFormSetHelper(BaseFormSetHelper):
def __init__(self, *args, **kwargs):
super(DecryptionFormSetHelper, self).__init__(*args, **kwargs)
self.form_show_labels = False
self.layout = Layout(
Div(
PrependedText('text', 'Cipher '),
css_class="formset_object")
)
class TrusteeFormSetHelper(BaseFormSetHelper):
def __init__(self, *args, **kwargs):
super(TrusteeFormSetHelper, self).__init__(*args, **kwargs)
self.layout = Layout(
Div(
Field('DELETE', css_class='input-small hidden'),
PrependedAppendedText('email', 'Email ', "<span data-toggle='tooltip' title='Delete this Trustee' class='glyphicon glyphicon-trash'></span>", placeholder="Email address of the trustee"),
css_class="formset_object")
)
class PollOptionFormSetHelper(BaseFormSetHelper):
def __init__(self, *args, **kwargs):
super(PollOptionFormSetHelper, self).__init__(*args, **kwargs)
self.layout = Layout(
Div(
Field('DELETE', css_class='input-small hidden'),
PrependedAppendedText('choice_text', 'Option', "<span class='glyphicon glyphicon-trash'></span>", placeholder="Option"),
css_class="formset_object")
)
class PollOptionFormSetHelper(BaseFormSetHelper):
def __init__(self, *args, **kwargs):
super(PollOptionFormSetHelper, self).__init__(*args, **kwargs)
self.layout = Layout(
Div(
Field('DELETE', css_class='input-small hidden'),
PrependedAppendedText('choice_text', 'Option', "<span class='glyphicon glyphicon-trash'></span>", placeholder="Option"),
css_class="formset_object")
)
### EXPERIMENTAL https://stackoverflow.com/questions/15157262/django-crispy-forms-nesting-a-formset-within-a-form/22053952#22053952
class Formset(LayoutObject):
"""
Layout object. It renders an entire formset, as though it were a Field.
Example::
Formset("attached_files_formset")
"""
template = "%s/formset.html" % TEMPLATE_PACK
def __init__(self, formset_name_in_context, template=None, helper=None):
self.formset_name_in_context = formset_name_in_context
# crispy_forms/layout.py:302 requires us to have a fields property
self.fields = []
# Overrides class variable with an instance level variable
if template:
self.template = template
if helper:
self.helper = helper
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
formset = context[self.formset_name_in_context]
return render_to_string(self.template, Context({'wrapper': self,
'formset': formset, 'helper': self.helper}))
class OptionForm(forms.ModelForm):
choice_text = forms.CharField(label=('Option'),
min_length=1, max_length=1024)
def clean_option(self):
return _trim_whitespace(self.cleaned_data['text'])
class Meta:
model = PollOption
fields = ('choice_text',)
OrganiserFormSet = forms.formset_factory(form=OrganiserForm, extra=0, min_num=1, max_num=10, can_delete=True)
TrusteeFormSet = forms.formset_factory(form=EmailForm, extra=1, min_num=1, max_num=10, can_delete=True)
DecryptionFormset = forms.formset_factory(form=DecryptionForm, extra=0, min_num=0, validate_min=True, max_num=20, can_delete=False)
OptionFormset = forms.inlineformset_factory(Poll, PollOption, form=OptionForm, min_num=2, max_num=20, validate_min=True, extra=0, fields=('choice_text',), can_delete=True)
QuestionFormset = forms.inlineformset_factory(Event, Poll, form=PollForm, extra=0, min_num=2, validate_min=True, max_num=20, can_delete=True)