class CarouselSlidesFormMixin(ManageChildrenFormMixin, EntangledModelFormMixin): OPTION_CHOICES = [('slide', _("Animate")), ('pause', _("Pause")), ('wrap', _("Wrap"))] num_children = IntegerField( min_value=1, initial=1, label=_('Slides'), help_text=_('Number of slides for this carousel.'), ) interval = IntegerField( label=_("Interval"), initial=5, help_text=_("Change slide after this number of seconds."), ) options = MultipleChoiceField( label=_('Options'), choices=OPTION_CHOICES, widget=widgets.CheckboxSelectMultiple, initial=['slide', 'wrap', 'pause'], help_text=_("Adjust interval for the carousel."), ) container_max_heights = BootstrapMultiSizeField( label=_("Carousel heights"), allowed_units=['rem', 'px'], initial=dict((bp.name, '{}rem'.format(6 + 3 * i)) for i, bp in enumerate(Breakpoint)), help_text= _("Heights of Carousel in pixels for distinct Bootstrap's breakpoints." ), ) resize_options = MultipleChoiceField( label=_("Resize Options"), choices=BootstrapPictureFormMixin.RESIZE_OPTIONS, widget=widgets.CheckboxSelectMultiple, help_text=_("Options to use when resizing the image."), initial=['upscale', 'crop', 'subject_location', 'high_resolution'], ) class Meta: untangled_fields = ['num_children'] entangled_fields = { 'glossary': ['interval', 'options', 'container_max_heights', 'resize_options'] }
def get_form(self, request, obj=None, **kwargs): form_fields = { 'plugin_type': ChoiceField(choices=self.plugins_for_site), } for style, choices_tuples in app_settings.CMSPLUGIN_CASCADE[ 'extra_inline_styles'].items(): form_fields['extra_fields:{0}'.format( style )] = MultipleChoiceField( label=_("Customized {0} fields:").format(style), choices=[(c, c) for c in choices_tuples[0]], required=False, widget=widgets.CheckboxSelectMultiple, help_text= _("Allow these extra inlines styles for the given plugin type." ), ) if issubclass(choices_tuples[1], SizeField): form_fields['extra_units:{0}'.format(style)] = ChoiceField( label=_("Units for {0} Fields:").format(style), choices=self.DISTANCE_UNITS, required=False, help_text=_( "Allow these size units for customized {0} fields."). format(style), ) inline_styles_fields = list(form_fields.keys()) form = type('PluginExtraFieldsForm', (PluginExtraFieldsForm, ), form_fields) form._meta.entangled_fields['inline_styles'] = inline_styles_fields kwargs.setdefault('form', form) return super().get_form(request, obj=None, **kwargs)
class ContainerFormMixin(EntangledModelFormMixin): breakpoints = MultipleChoiceField( label=_('Available Breakpoints'), choices=get_widget_choices(), widget=ContainerBreakpointsWidget(choices=get_widget_choices()), initial=[ bp.name for bp in app_settings.CMSPLUGIN_CASCADE['bootstrap4'] ['fluid_bounds'].keys() ], help_text=_("Supported display widths for Bootstrap's grid system."), ) fluid = BooleanField( label=_('Fluid Container'), initial=False, required=False, help_text=_( "Changing your outermost '.container' to '.container-fluid'.")) class Meta: entangled_fields = {'glossary': ['breakpoints', 'fluid']} def clean_breapoints(self): # TODO: check this if len(self.cleaned_data['glossary']['breakpoints']) == 0: raise ValidationError( _("At least one breakpoint must be selected.")) return self.cleaned_data['glossary']
def _define_multifield(self, item, required, tname, lang): return MultipleChoiceField( choices=self._get_thesauro_keyword_label(item, lang), widget=autocomplete.Select2Multiple( url=f"/base/thesaurus_available/?sysid={item.id}&lang={lang}"), label=f"{tname}", required=required, )
def __init__(self, items, *args, **kwargs): super(PaymentHiddenInputsPostForm, self).__init__(*args, **kwargs) for key in items: if type(items[key]) in [list, tuple]: self.fields[key] = MultipleChoiceField( initial=items[key], widget=widgets.MultipleHiddenInput) else: self.fields[key] = CharField(initial=items[key], widget=HiddenInput)
def get_multiplechoice_field(field, choices): '''Generate a MultipleChoiceField form element :param field: Model Field to use :type field: django model field :param choices: List of choices for form field :type choices: iterable :returns: `MultipleChoiceField` :raises: ValueError ''' if not choices == []: return MultipleChoiceField(label=field.verbose_name, required=False, widget=CheckboxSelectMultiple, choices=choices) else: raise ValueError("%s does not have choices. " "MultipleChoiceField is inappropriate" % field.verbose_name)
def __new__(cls, choices): named_css_classes = MultipleChoiceField( label=_("Extra Styles"), choices=choices, widget=CheckboxSelectMultiple, required=False, ) class Meta: entangled_fields = {'glossary': ['named_css_classes']} attrs = { 'named_css_classes': named_css_classes, 'Meta': Meta, } utility_form_mixin = type('UtilitiesFormMixin', (EntangledModelFormMixin, ), attrs) return type('NamedCSSClassesMixin', (CascadeUtilitiesMixin, ), {'utility_form_mixin': utility_form_mixin})
def __init__(self, label=None, required=True, help_text=None, widget=None): fields_list = [] for el in settings.THESAURI: #widget=widgets.SelectMultiple #def __init__(self, *args, **kwargs): # super(MultiThesauriField, self).__init__(*args, **kwargs) # self.require_all_fields = kwargs.pop('require_all_fields', True) # if hasattr(settings, 'THESAURI') and settings.THESAURI: #el=settings.THESAURI choices_list = [] #fields_list=[] thesaurus_name = el['name'] #logger.error("MULTITHESAURIFIELD") #logger.error(thesaurus_name) try: t = Thesaurus.objects.get(identifier=thesaurus_name) for tk in t.thesaurus.all(): tkl = tk.keyword.filter(lang='en') choices_list.append((tkl[0].id, tkl[0].label)) logger.error(tkl[0].label) #logger.error(tkl[0].id) fields_list.append( MultipleChoiceField(choices=tuple(choices_list))) #logger.error(choices_list) #self.fields += (MultipleChoiceField(choices=tuple(choices_list)), ) #logger.error(self.fields) except BaseException: tb = traceback.format_exc() logger.error(tb) fields = tuple(fields_list) #fields=self.fields logger.error("FIELD") #logger.error(len(fields)) super(MultiThesauriField, self).__init__(fields, required, widget, label)
class HPCForm(forms.Form): HPC_APPS = ['', 'HRMC'] hpc_apps = ChoiceField(label="HPC App", required=True, choices=[(x, x) for x in HPC_APPS]) HPC_PROVIDERS = ['', 'NeCTAR'] #, 'NCI', 'MASSIVE'] NECTAR_VM_SIZES = ['', 'small', 'medium', 'large', 'extra large'] destination = ChoiceField(required=True, choices=[(x, x) for x in HPC_PROVIDERS]) STAGES = ['Create', 'Setup', 'Run', 'Terminate'] stages = MultipleChoiceField(required=True, choices=[(x, x) for x in STAGES], widget=CheckboxSelectMultiple) number_of_cores = forms.IntegerField(min_value=1) group_id = forms.CharField( label="Group ID", required=True, widget=widgets.TextInput(attrs={'class': 'required'}))
def get(self, request: HttpRequest, *args: Tuple, **kwargs: Dict[str, Any]): initial = {} context = {} hotel = get_object_or_404(Hotel, hotel_id=kwargs['hotel_id']) initial['hotel'] = hotel form = ReservationForm(initial=initial) # NOTE: refactor these fields - duplicate in POST body. svcs = form.get_services(hotel) form.fields['service'] = MultipleChoiceField( required=False, choices=svcs, widget=forms.CheckboxSelectMultiple()) bkfst = form.get_breakfast(hotel) form.fields['breakfast'] = EmptyChoiceField( required=False, choices=bkfst, empty_label='---- none ----') #, widget=CheckboxInput()) # rooms = form.get_rooms(hotel) form.fields['room_choice'] = ChoiceField(required=True, choices=rooms) if len(rooms) > 0: disc = form.get_discounts(rooms[0][0], form.fields['check_in'], form.fields['check_out']) form.fields['discount'] = CharField( initial=disc, required=False, widget=forms.TextInput(attrs={'readonly': 'readonly'})) # END refactor user = request.user context['form'] = form return render(request, 'bookhotel.html', context)
class FieldsConfigEditForm(CremeModelForm): hidden = MultipleChoiceField(label=_(u'Hidden fields'), choices=(), required=False) class Meta(CremeModelForm.Meta): model = FieldsConfig def __init__(self, *args, **kwargs): # super(FieldsConfigEditForm, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs) instance = self.instance hidden_f = self.fields['hidden'] hidden_f.choices = FieldsConfig.field_enumerator(instance.content_type.model_class()).choices() if instance.pk: hidden_f.initial = [f.name for f in instance.hidden_fields] def save(self, *args, **kwargs): # TODO: in clean for ValidationErrors ?? HIDDEN = FieldsConfig.HIDDEN self.instance.descriptions = [(field_name, {HIDDEN: True}) for field_name in self.cleaned_data['hidden'] ] # return super(FieldsConfigEditForm, self).save(*args, **kwargs) return super().save(*args, **kwargs)
class ProjectProfile(Form): PROJECT_TYPE_CHOICES = (('survey', 'Survey project: I want to collect data from the field'), ('public information', 'Public information: I want to send information')) DEVICE_CHOICES = (('sms', 'SMS'),) SUBJECT_TYPE_CHOICES = (('yes','Work performed by the data sender (eg. monthly activity report)'),('no','Other Subject')) GROUP_TYPE_CHOICES = (('open','Open Data Sender Group. Anyone can send in data without registering'),('close','Closed Data Sender Group. Only registered data sender will be able to send data')) id = CharField(required=False) name = CharField(required=True, label="Name this Project") goals = CharField(max_length=300, widget=forms.Textarea, label='Project Description', required=False) project_type = ChoiceField(label='Project Type', widget=MyRadioSelect, choices=PROJECT_TYPE_CHOICES) sender_group = ChoiceField(label='Open or Closed Group', widget=MyRadioSelect, choices=GROUP_TYPE_CHOICES) activity_report = ChoiceField(label="What is this questionnaire about?", widget=forms.RadioSelect, choices=SUBJECT_TYPE_CHOICES, initial=('no','Other Subject')) entity_type = ChoiceField(label="Other Subjects", required=False) devices = MultipleChoiceField(label='Device', widget=forms.CheckboxSelectMultiple, choices=DEVICE_CHOICES, initial=DEVICE_CHOICES[0], required=False) def __init__(self, entity_list, *args, **kwargs): assert isinstance(entity_list, list) super(ProjectProfile, self).__init__(*args, **kwargs) entity_list = entity_list self.fields['entity_type'].choices = [(t[-1], t[-1]) for t in entity_list] self.fields['name'].widget.attrs['watermark'] = "Enter a project name" self.fields['goals'].widget.attrs['watermark'] = "Describe what your team hopes to achieve by collecting this data" def clean_entity_type(self): if self.cleaned_data.get('entity_type') == "" and self.cleaned_data.get("activity_report") == 'no' : raise ValidationError("This field is required") return self.cleaned_data.get('entity_type') def clean(self): if self.cleaned_data.get("activity_report") == 'yes': self.cleaned_data['entity_type'] = REPORTER if self.errors.get('entity_type') is not None: self.errors['entity_type'] = "" return self.cleaned_data
class RemoveForm(Form): remove = MultipleChoiceField(required=False, choices=()) def __init__(self, request, choices, *args, **kwargs): super(Form, self).__init__(request, *args, **kwargs) self.fields['remove'].choices = choices
def _formfield(self, initial): return MultipleChoiceField( choices=self._args['choices'], initial=initial, widget=UnorderedMultipleChoiceWidget(columntype='wide'), )
class ScreenslopForm(Form): url = URLField() viewports = MultipleChoiceField(choices=AVAILABLE_RESOLUTIONS, widget=CheckboxSelectMultiple)
class JadouNums(forms.Form): jnums = MultipleChoiceField(widget=CheckboxSelectMultiple(), choices=JADOUNUMS)
class ReporterRegistrationForm(Form): required_css_class = 'required' name = RegexField( regex="[^0-9.,\s@#$%&*~]*", max_length=20, error_message= _("Please enter a valid value containing only letters a-z or A-Z or symbols '`- " ), label=_("Name")) telephone_number = PhoneNumberField(required=True, label=_("Mobile Number")) geo_code = CharField(max_length=30, required=False, label=_("GPS: Enter Lat Long")) location = CharField(max_length=100, required=False, label=_("Name")) project_id = CharField(required=False, widget=HiddenInput()) DEVICE_CHOICES = ( ('sms', mark_safe( '<img src="/media/images/mini_mobile.png" /> <span>SMS</span>')), ('web', mark_safe( '<img src="/media/images/mini_computer.png" /> <span>Web</span>' + smartphone_icon()))) devices = MultipleChoiceField( label=_('Device'), widget=CheckboxSelectMultiple(), choices=DEVICE_CHOICES, initial=['sms'], required=False, ) email = EmailField( required=False, widget=TextInput(attrs=dict({'class': 'required'}, maxlength=75)), label=_("Email address"), error_messages={ 'invalid': _('Enter a valid email address. Example:[email protected]') }) short_code = RegexField( "^[a-zA-Z0-9]+$", label=_("Unique ID"), required=False, widget=TextInput(attrs=dict({ 'class': 'subject_field', 'disabled': 'disabled' })), error_message=_("Only letters and numbers are valid")) # Needed for telephone number validation org_id = None def __init__(self, org_id=None, *args, **kwargs): self.org_id = org_id super(ReporterRegistrationForm, self).__init__(*args, **kwargs) def _is_int(self, s): try: int(s) return True except ValueError: return False def _geo_code_format_validations(self, lat_long, msg): if len(lat_long) != 2: self._errors['geo_code'] = self.error_class([msg]) else: try: if not (-90 < float(lat_long[0]) < 90 and -180 < float(lat_long[1]) < 180): self._errors['geo_code'] = self.error_class([msg]) except Exception: self._errors['geo_code'] = self.error_class([msg]) def _geo_code_validations(self, b): msg = _( "Incorrect GPS format. The GPS coordinates must be in the following format: xx.xxxx,yy.yyyy. Example -18.8665,47.5315" ) geo_code_string = b.strip() geo_code_string = (' ').join(geo_code_string.split()) if not is_empty(geo_code_string): lat_long = filter(None, re.split("[ ,]", geo_code_string)) self._geo_code_format_validations(lat_long, msg) self.cleaned_data['geo_code'] = geo_code_string def clean(self): self.convert_email_to_lowercase() location = self.cleaned_data.get("location").strip() geo_code = self.cleaned_data.get("geo_code").strip() if not (bool(location) or bool(geo_code)): msg = _("Please fill out at least one location field correctly.") self._errors['location'] = self.error_class([msg]) self._errors['geo_code'] = self.error_class([msg]) if bool(geo_code): self._geo_code_validations(geo_code) return self.cleaned_data def clean_telephone_number(self): """ Validate telephone number. This expects the dbm to be set on the form before trying to clean. """ organization = Organization.objects.get(org_id=self.org_id) if organization.in_trial_mode: if DataSenderOnTrialAccount.objects.filter(mobile_number=( self.cleaned_data.get('telephone_number'))).exists(): self._errors['telephone_number'] = self.error_class([( u"Sorry, this number has already been used for a different DataWinners trial account." )]) return self.cleaned_data.get('telephone_number') def clean_email(self): """ Validate that the supplied email address is unique for the site. """ if not self.requires_web_access(): return None email = self.cleaned_data.get('email') if is_empty(email): msg = _('This field is required.') self._errors['email'] = self.error_class([msg]) return None if User.objects.filter(email__iexact=self.cleaned_data['email']): raise forms.ValidationError( _("This email address is already in use. Please supply a different email address." )) return self.cleaned_data['email'] def convert_email_to_lowercase(self): email = self.cleaned_data.get('email') if email is not None: self.cleaned_data['email'] = email.lower() def requires_web_access(self): devices = self.cleaned_data.get('devices') return devices.__contains__('web') def update_errors(self, validation_errors): mapper = {MOBILE_NUMBER_FIELD_CODE: 'telephone_number'} validation_error = validation_errors.get(MOBILE_NUMBER_FIELD_CODE) self._errors[mapper[MOBILE_NUMBER_FIELD_CODE]] = self.error_class( [validation_error]) def clean_short_code(self): short_code = self.cleaned_data.get('short_code') if short_code: self.fields.get("short_code").widget.attrs.pop("disabled") return short_code
class RecoverObjectWithTranslationForm(forms.Form): translations = MultipleChoiceField( required=True, widget=CheckboxSelectMultiple(), label=_('Translations to restore:'), help_text=_('Please select translations which would be restored.')) def __init__(self, *args, **kwargs): # prepare data for misc lookups self.revision = kwargs.pop('revision') self.obj = kwargs.pop('obj') self.version = kwargs.pop('version') self.resolve_conflicts = kwargs.pop('resolve_conflicts') self.placeholders = kwargs.pop('placeholders') # do not check object which needs to be recovered versions = self.revision.version_set.exclude(pk=self.version.pk) super(RecoverObjectWithTranslationForm, self).__init__(*args, **kwargs) translatable = hasattr(self.obj, 'translations') if translatable: translation_versions = get_translations_versions_for_object( self.obj, self.revision, versions) # update form choices = [(translation_version.pk, force_text(translation_version)) for translation_version in translation_versions] self.fields['translations'].choices = choices else: # do not show translations options if object is not translated self.fields.pop('translations') def clean(self): data = super(RecoverObjectWithTranslationForm, self).clean() # if there is self.resolve_conflicts do not count them as conflicts exclude = { 'pk__in': [ version.pk for version in self.resolve_conflicts + self.placeholders ] } conflict_fks_versions = get_conflict_fks_versions(self.obj, self.version, self.revision, exclude=exclude) if bool(conflict_fks_versions): raise ValidationError( _('Cannot restore object, there are conflicts!'), code='invalid') return data def save(self): # restore placeholders for placeholder_version in self.placeholders: # note that only placeholders are being reverted, assuming that # cms plugins that are related to this placeholder were not deleted placeholder_version.revert() # if there is self.resolve_conflicts revert those objects to avoid # integrity errors, because user cannot do that form admin # assume that that was prepared for us in admin view for conflict in self.resolve_conflicts: conflict.revert() # revert main object self.version.revert() # revert translations, if there is translations translations_pks = self.cleaned_data.get( 'translations', []) if hasattr(self, 'cleaned_data') else [] translation_versions = self.revision.version_set.filter( pk__in=translations_pks) if translations_pks else [] for translation_version in translation_versions: translation_version.revert()
def get_form(self, request, obj=None, **kwargs): from cmsplugin_cascade.models import PluginExtraFields from .config import PluginExtraFieldsConfig clsname = self.__class__.__name__ try: site = get_current_site(request) extra_fields = PluginExtraFields.objects.get(plugin_type=clsname, site=site) except ObjectDoesNotExist: extra_fields = app_settings.CMSPLUGIN_CASCADE['plugins_with_extra_fields'].get(clsname) if isinstance(extra_fields, (PluginExtraFields, PluginExtraFieldsConfig)): form_fields = {} # add a text input field to let the user name an ID tag for this HTML element if extra_fields.allow_id_tag: form_fields['extra_element_id'] = CharField( label=_("Named Element ID"), ) # add a select box to let the user choose one or more CSS classes class_names, choices = extra_fields.css_classes.get('class_names'), None if isinstance(class_names, (list, tuple)): choices = [(clsname, clsname) for clsname in class_names] elif isinstance(class_names, str): choices = [(clsname, clsname) for clsname in class_names.replace(' ', ',').split(',') if clsname] if choices: if extra_fields.css_classes.get('multiple'): form_fields['extra_css_classes'] = MultipleChoiceField( label=_("Customized CSS Classes"), choices=choices, required=False, widget=widgets.CheckboxSelectMultiple, help_text=_("Customized CSS classes to be added to this element."), ) else: choices.insert(0, (None, _("Select CSS"))) form_fields['extra_css_classes'] = ChoiceField( label=_("Customized CSS Class"), choices=choices, required=False, help_text=_("Customized CSS class to be added to this element."), ) # add input fields to let the user enter styling information for style, choices_list in app_settings.CMSPLUGIN_CASCADE['extra_inline_styles'].items(): inline_styles = extra_fields.inline_styles.get('extra_fields:{0}'.format(style)) if not inline_styles: continue Field = choices_list[1] for inline_style in inline_styles: key = 'extra_inline_styles:{0}'.format(inline_style) field_kwargs = { 'label': '{0}: {1}'.format(style, inline_style), 'required': False, } if issubclass(Field, SizeField): field_kwargs['allowed_units'] = extra_fields.inline_styles.get('extra_units:{0}'.format(style)).split(',') form_fields[key] = Field(**field_kwargs) # extend the form with some extra fields base_form = kwargs.pop('form', self.form) assert issubclass(base_form, EntangledModelFormMixin), "Form must inherit from EntangledModelFormMixin" class Meta: entangled_fields = {'glossary': list(form_fields.keys())} form_fields['Meta'] = Meta kwargs['form'] = type(base_form.__name__, (base_form,), form_fields) return super().get_form(request, obj, **kwargs)
class ButtonFormMixin(EntangledModelFormMixin): BUTTON_TYPES = [ ('btn-primary', _("Primary")), ('btn-secondary', _("Secondary")), ('btn-success', _("Success")), ('btn-danger', _("Danger")), ('btn-warning', _("Warning")), ('btn-info', _("Info")), ('btn-light', _("Light")), ('btn-dark', _("Dark")), ('btn-link', _("Link")), ('btn-outline-primary', _("Primary")), ('btn-outline-secondary', _("Secondary")), ('btn-outline-success', _("Success")), ('btn-outline-danger', _("Danger")), ('btn-outline-warning', _("Warning")), ('btn-outline-info', _("Info")), ('btn-outline-light', _("Light")), ('btn-outline-dark', _("Dark")), ('btn-outline-link', _("Link")), ] BUTTON_SIZES = [ ('btn-lg', _("Large button")), ('', _("Default button")), ('btn-sm', _("Small button")), ] link_content = CharField( required=False, label=_("Button Content"), widget=widgets.TextInput(attrs={'size': 50}), ) button_type = ChoiceField( label=_("Button Type"), widget=ButtonTypeWidget(choices=BUTTON_TYPES), choices=BUTTON_TYPES, initial='btn-primary', help_text=_("Display Link using this Button Style")) button_size = ChoiceField( label=_("Button Size"), widget=ButtonSizeWidget(choices=BUTTON_SIZES), choices=BUTTON_SIZES, initial='', required=False, help_text=_("Display Link using this Button Size")) button_options = MultipleChoiceField( label=_("Button Options"), choices=[ ('btn-block', _('Block level')), ('disabled', _('Disabled')), ], required=False, widget=widgets.CheckboxSelectMultiple, ) stretched_link = BooleanField( label=_("Stretched link"), required=False, help_text=_("Stretched-link utility to make any anchor the size of it’s nearest position: " \ "relative parent, perfect for entirely clickable cards!") ) icon_align = ChoiceField( label=_("Icon alignment"), choices=[ ('icon-left', _("Icon placed left")), ('icon-right', _("Icon placed right")), ], widget=widgets.RadioSelect, initial='icon-right', help_text=_("Add an Icon before or after the button content."), ) class Meta: entangled_fields = { 'glossary': [ 'link_content', 'button_type', 'button_size', 'button_options', 'icon_align', 'stretched_link' ] }
class ReporterRegistrationForm(Form): required_css_class = 'required' name = RegexField(regex="[^0-9.,\s@#$%&*~]*", max_length=80, error_message=_("Please enter a valid value containing only letters a-z or A-Z or symbols '`- "), label=_("Name"), required=False) telephone_number = PhoneNumberField(required=True, label=_("Mobile Number"), error_message=_("Please enter a valid phone number.")) geo_code = CharField(max_length=30, required=False, label=_("GPS Coordinates")) location = CharField(max_length=500, required=False, label=_("Name")) project_id = CharField(required=False, widget=HiddenInput()) DEVICE_CHOICES = (('sms', mark_safe('<img src="/media/images/mini_mobile.png" /> <span>SMS</span>')), ( 'web', mark_safe('<img src="/media/images/mini_computer.png" /> <span>Web</span>' + smartphone_icon()))) devices = MultipleChoiceField(label=_('Device'), widget=CheckboxSelectMultiple(), choices=DEVICE_CHOICES, initial=['sms'], required=False, ) email = EmailField(required=False, widget=TextInput(attrs=dict({'class': 'required'}, maxlength=75)), label=_("E-Mail"), error_messages={ 'invalid': _('Enter a valid email address. Example:[email protected]')}) short_code = CharField(required=False, max_length=12, label=_("ID"), widget=TextInput(attrs=dict({'class': 'subject_field'}))) generated_id = BooleanField(required=False, initial=True) # Needed for telephone number validation org_id = None def __init__(self, org_id=None, *args, **kwargs): self.org_id = org_id super(ReporterRegistrationForm, self).__init__(*args, **kwargs) def _is_int(self, s): try: int(s) return True except ValueError: return False def _geo_code_format_validations(self, lat_long, msg): if len(lat_long) != 2: self._errors['geo_code'] = self.error_class([msg]) else: try: if not (-90 < float(lat_long[0]) < 90 and -180 < float(lat_long[1]) < 180): self._errors['geo_code'] = self.error_class([msg]) except Exception: self._errors['geo_code'] = self.error_class([msg]) def _geo_code_validations(self): geo_code = self.cleaned_data.get("geo_code").strip() if not bool(geo_code): return msg = _( "Incorrect GPS format. The GPS coordinates must be in the following format: xx.xxxx,yy.yyyy. Example -18.8665,47.5315") geo_code_string = geo_code.strip() geo_code_string = geo_code_string.replace(",", " ") geo_code_string = re.sub(' +', ' ', geo_code_string) if not is_empty(geo_code_string): lat_long = geo_code_string.split(" ") self._geo_code_format_validations(lat_long, msg) self.cleaned_data['geo_code'] = geo_code_string def clean(self): self.convert_email_to_lowercase() if not self.cleaned_data.get('generated_id') and not self.cleaned_data.get('short_code'): msg = _('This field is required.') self.errors['short_code'] = self.error_class([msg]) self._geo_code_validations() if not self.cleaned_data.get('project_id'): self.cleaned_data['is_data_sender'] = False else: self.cleaned_data['is_data_sender'] = 'True' return self.cleaned_data def clean_short_code(self): short_code = self.cleaned_data.get('short_code') if short_code: if len(short_code) > 12: msg = _("Unique ID should be less than 12 characters") self.errors['short_code'] = self.error_class([msg]) if not re.match("^[a-zA-Z0-9]+$", short_code): msg = _("Only letters and numbers are valid") self.errors['short_code'] = self.error_class([msg]) return short_code def clean_telephone_number(self): """ Validate telephone number. This expects the dbm to be set on the form before trying to clean. """ organization = Organization.objects.get(org_id=self.org_id) mobile_number = self.cleaned_data.get('telephone_number') if organization.in_trial_mode: datasender_filter = DataSenderOnTrialAccount.objects.filter(mobile_number=(mobile_number)) if datasender_filter.exclude(organization=organization).exists(): self._errors['telephone_number'] = self.error_class( [_(u"Sorry, this number has already been used for a different DataWinners Basic account.")]) return mobile_number def clean_email(self): """ Validate that the supplied email address is unique for the site. """ email = self.cleaned_data.get('email') if not email: return email if datasender_count_with(email) > 0: raise forms.ValidationError( _("This email address is already in use. Please supply a different email address.")) return self.cleaned_data['email'] def convert_email_to_lowercase(self): email = self.cleaned_data.get('email') if email is not None: self.cleaned_data['email'] = email.lower() def requires_web_access(self): return self.cleaned_data.get('email') def update_errors(self, validation_errors): mapper = {MOBILE_NUMBER_FIELD_CODE: 'telephone_number', GEO_CODE: GEO_CODE_FIELD_NAME} for field_code, error in validation_errors.iteritems(): self._errors[mapper.get(field_code)] = self.error_class([_(error)])
def post(self, request: HttpRequest, *args: Tuple, **kwargs: Dict[str, Any]): form = ReservationForm(request.POST) hotel = get_object_or_404(Hotel, hotel_id=kwargs['hotel_id']) # NOTE: refactor these fields svcs = form.get_services(hotel) form.fields['service'] = MultipleChoiceField( required=False, choices=svcs, widget=forms.CheckboxSelectMultiple()) bkfst = form.get_breakfast(hotel) form.fields['breakfast'] = EmptyChoiceField( required=False, choices=bkfst, empty_label='---- none ----') #, widget=CheckboxInput()) # rooms = form.get_rooms(hotel) form.fields['room_choice'] = ChoiceField(required=True, choices=rooms) if len(rooms) > 0: disc = form.get_discounts(rooms[0][0], form.fields['check_in'], form.fields['check_out']) form.fields['discount'] = CharField( initial=disc, required=False, widget=forms.TextInput(attrs={'readonly': 'readonly'})) # END refactor user = request.user context = {} messages = [] context = {'form': form} if form.is_valid(): if form.cleaned_data['check_in'] < datetime.datetime.today().date( ): messages.append('check in today or future') if form.cleaned_data['check_in'] >= form.cleaned_data['check_out']: messages.append('check out must be greater than check in') # checks: cc date in future cc_exp_date = datetime.date( int(form.cleaned_data['credit_card_year']), int(form.cleaned_data['credit_card_month']), 1) if cc_exp_date < datetime.date.today(): messages.append('credit card date must be greater than today') # we can now persist. if len(messages) == 0: s_list = [] for s in form.cleaned_data['service']: s_list.append(Service.objects.get(pk=s)) new_booking = BookingRequest( hotel, form.cleaned_data['room_choice'], form.cleaned_data['credit_card_number'], form.cleaned_data['credit_card_type'], form.cleaned_data['credit_card_month'], form.cleaned_data['credit_card_year'], form.cleaned_data['credit_card_code'], form.cleaned_data['credit_card_address'], form.cleaned_data['credit_card_name'], request.user, datetime.date.today(), form.cleaned_data['check_in'], form.cleaned_data['check_out'], form.cleaned_data['breakfast'], form.cleaned_data['breakfast_number_orders'], s_list, ) # order of saving: # 1. credit card x # 2. reservation x # 3. room_reservation x # 4. rresb_breakfast x # 5. rresv_service x @transaction.atomic def save_reservation(n_req: BookingRequest): card = CreditCard() card.address = n_req.credit_card_address card.cc_number = n_req.credit_card_number card.cc_type = n_req.credit_card_type card.cv_code = n_req.credit_card_code exp_date = datetime.date(int(n_req.credit_card_year), int(n_req.credit_card_month), 1) card.expiration_date = exp_date card.save() resv = Reservation() resv.cid = n_req.cust_id resv.r_date = n_req.res_date # grab the key resv.cc_number = card resv.save() room = Room.objects.get(pk=n_req.room) rr_resv = RoomReservation() rr_resv.check_in_date = n_req.check_in rr_resv.check_out_date = n_req.check_out rr_resv.hotel_id = n_req.hotel # grab the key rr_resv.room_no = room rr_resv.invoice_number = resv rr_resv.save() # breakfast if len(n_req.breakfast) > 0: br = ReservationBreakfast() br.bid = Breakfast.objects.get(pk=n_req.breakfast) br.nooforders = n_req.breakfast_number_orders br.rr_id = rr_resv # resv br.save() # services for s in n_req.svc_id: resv_svc = ReservationService() resv_svc.sid = s resv_svc.rr_id = rr_resv # resv resv_svc.sprice = s.s_price resv_svc.save() save_reservation(new_booking) return HttpResponseRedirect(f'/reservations/bookings/') context['messages'] = messages return render(request, 'bookhotel.html', context) else: messages.append('form is invalid') for e in form.errors: messages.append(e) context['messages'] = messages return render(request, 'bookhotel.html', context)