コード例 #1
0
class SameAsForm(forms.Form):
    """Define "same as" for two contacts"""
    contact = forms.IntegerField(label=_("Contact"))

    def __init__(self, contact, *args, **kwargs):
        super(SameAsForm, self).__init__(*args, **kwargs)
        potential_contacts = get_suggested_same_as_contacts(
            contact_id=contact.id,
            lastname=contact.lastname,
            firstname=contact.firstname,
            email=contact.email)
        if contact.same_as:
            # Do not propose again current SameAs
            potential_contacts = potential_contacts.exclude(
                same_as=contact.same_as)
        self._same_as = [(same_as_contact.id, "{0}".format(same_as_contact))
                         for same_as_contact in potential_contacts]
        if len(self._same_as):
            self.fields["contact"].widget = forms.Select(choices=self._same_as)
        else:
            self.fields["contact"].widget = forms.HiddenInput()

    def has_choices(self):
        """true if several contacts with same name"""
        return len(self._same_as)

    def clean_contact(self):
        """validation"""
        contact_id = self.cleaned_data["contact"]
        try:
            if contact_id not in [same_as[0] for same_as in self._same_as]:
                raise ValidationError(ugettext("Invalid contact"))
            return models.Contact.objects.get(id=contact_id)
        except models.Contact.DoesNotExist:
            raise ValidationError(ugettext("Contact does not exist"))
コード例 #2
0
class UserEmailConfirmationForm(forms.Form):
    email = forms.EmailField()
    secret = forms.CharField(min_length=32, max_length=32)
    user_id = forms.IntegerField()

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super(UserEmailConfirmationForm, self).__init__(*args, **kwargs)

    def clean_user_id(self):
        user_id = self.cleaned_data['user_id']
        if user_id != self.user.pk:
            raise forms.ValidationError(
                _('Logged in user does not match this link!'))
        return user_id

    def clean(self):
        check = AccountManager(self.user).check_confirmation_secret(
            self.cleaned_data['secret'],
            self.cleaned_data['email'],
        )
        if not check:
            raise forms.ValidationError(_('Link is invalid or has expired!'))
        return self.cleaned_data

    def save(self):
        self.user.email = self.cleaned_data['email']
        self.user.save()
コード例 #3
0
ファイル: thread.py プロジェクト: artscoop/scoop
class ThreadForm(MessageForm):
    """ Formulaire de fil de discussion """
    # Constantes
    SUBJECT_LENGTH_MIN = 1
    # Champs supplémentaires
    subject = forms.CharField(max_length=48,
                              required=False,
                              widget=forms.TextInput())
    recipient = forms.IntegerField(required=True, widget=forms.HiddenInput())

    # Validation
    def clean_subject(self):
        """ Valider et renvoyer les données du champ sujet """
        subject = self.data['subject']
        if len(subject) < ThreadForm.SUBJECT_LENGTH_MIN:
            raise forms.ValidationError(
                _("Your subject must be at least {} characters long.").format(
                    ThreadForm.SUBJECT_LENGTH_MIN))
        return subject

    def clean_recipient(self):
        """ Valider et renvoyer les données du champ destinataire """
        recipient = int(self.data['recipient'])
        if get_user_model().objects.get_or_none(id=recipient) is None:
            raise forms.ValidationError(_("The recipient does not exist."))
        return get_user_model().objects.get(id=recipient)
コード例 #4
0
ファイル: forms.py プロジェクト: wangjing161/moztrap
class EditCaseVersionForm(mtforms.SaveIfValidMixin,
                          BaseCaseVersionForm,
                          BaseCaseForm,
                          ):
    """Form for editing a case version."""
    cc_version = forms.IntegerField(widget=forms.HiddenInput)


    def __init__(self, *args, **kwargs):
        """Initialize EditCaseVersionForm, pulling instance from kwargs."""
        self.instance = kwargs.pop("instance", None)

        initial = kwargs.setdefault("initial", {})
        initial["name"] = self.instance.name
        initial["description"] = self.instance.description
        initial["status"] = self.instance.status
        initial["cc_version"] = self.instance.cc_version

        initial["idprefix"] = self.instance.case.idprefix
        initial["priority"] = self.instance.case.priority

        super(EditCaseVersionForm, self).__init__(*args, **kwargs)


    def save(self, user=None):
        """Save the edited caseversion."""
        user = user or self.user
        assert self.is_valid()

        version_kwargs = self.cleaned_data.copy()
        del version_kwargs["add_tags"]
        del version_kwargs["add_attachment"]

        idprefix = version_kwargs.pop("idprefix")
        priority = version_kwargs.pop("priority")

        for k, v in version_kwargs.items():
            setattr(self.instance, k, v)

        if self.instance.case.idprefix != idprefix:
            self.instance.case.idprefix = idprefix
            self.instance.case.save(force_update=True)

        if self.instance.case.priority != priority:
            try:
                int(priority)
            except ValueError:
                priority = None
            self.instance.case.priority = priority
            self.instance.case.save(force_update=True)

        self.instance.save(force_update=True)

        self.save_new_tags(self.instance.case.product)
        self.save_tags(self.instance)
        self.save_attachments(self.instance)
        self.steps_formset.save(user=user)

        return self.instance
コード例 #5
0
 def __init__(self, *args, **kwargs):
     super(SRForm, self).__init__(*args, **kwargs)
     curmax = int(kwargs['instance'].sender.participant.vars['herd_size'])
     self.fields['amount_sent'] = forms.IntegerField(label='How many cattle will you send this player?',
                                                     required=True,
                                                     max_value=curmax,
                                                     min_value=0,
                                                     )
コード例 #6
0
ファイル: forms.py プロジェクト: BenjCherpas/balafon
class UpdateFavoriteForm(forms.Form):
    object_id = forms.IntegerField(required=True)
    content_type = ContentTypeField(required=True)
    
    def __init__(self, *args, **kwargs):
        instance = kwargs.pop('instance', None)
        if instance:
            kwargs['initial'] = {
                'object_id': instance.id,
                'content_type': ContentType.objects.get_for_model(instance.__class__).id,
            }
        super(UpdateFavoriteForm, self).__init__(*args, **kwargs)
コード例 #7
0
 def __init__(self, *args, **kwargs):
     choices = kwargs.pop('choices', None)
     super(SelectContactForm, self).__init__(*args, **kwargs)
     if choices:
         widget = forms.Select(choices=[(x.id, x.fullname)
                                        for x in choices])
         self.fields["contact"] = forms.IntegerField(label=_("Contact"),
                                                     widget=widget)
     else:
         widget = ContactAutoComplete(
             attrs={
                 'placeholder': _('Enter the name of a contact'),
                 'size': '50',
                 'class': 'colorbox'
             })
         self.fields["contact"] = forms.CharField(label=_("Contact"),
                                                  widget=widget)
コード例 #8
0
class SameAsPriorityForm(BetterBsForm):
    """Define "same as" priority for a contact"""
    priority = forms.IntegerField(label=_("Priority"))

    def __init__(self, contact, *args, **kwargs):
        super(SameAsPriorityForm, self).__init__(*args, **kwargs)
        self.contact = contact
        self.fields['priority'].initial = contact.same_as_priority

    def clean_priority(self):
        """make sure that the priority is an integer between 1 and number of same as"""
        value = self.cleaned_data['priority']
        min_value = 1
        max_value = self.contact.same_as.contact_set.count()
        if value < min_value or value > max_value:
            raise ValidationError(
                ugettext(
                    'Invalid value : It should be between {0} and {1}').format(
                        min_value, max_value))
        return value
コード例 #9
0
class SameAsSuggestionForm(forms.Form):
    """
    generate suggestion list from a few data.
    This form is not displayed and used by json API
    """
    id = forms.IntegerField(required=False)
    lastname = forms.CharField(required=False)
    firstname = forms.CharField(required=False)
    email = forms.CharField(required=False)

    def get_suggested_contacts(self):
        """return list a suggestions for same as"""
        contact_id = self.cleaned_data['id']
        lastname = self.cleaned_data['lastname']
        firstname = self.cleaned_data['firstname']
        email = self.cleaned_data['email']
        return get_suggested_same_as_contacts(contact_id=contact_id,
                                              lastname=lastname,
                                              firstname=firstname,
                                              email=email)
コード例 #10
0
class RegistrationForm(forms.Form):
    honeypot = forms.CharField(required=False, widget=forms.HiddenInput)
    firstname = forms.CharField(label=_('Your first name?'))
    lastname = forms.CharField(label=_('Your last name:'))
    username = forms.CharField(max_length=30)
    password = forms.CharField(
        widget=forms.PasswordInput,
        help_text=_('Make sure to use a secure password.'),
    )
    password2 = forms.CharField(label=_('Retype password'), widget=forms.PasswordInput)
    age = forms.IntegerField(required=False)
    height = forms.DecimalField(localize=True, required=False)
    agree_to_terms = forms.BooleanField()

    def clean_honeypot(self):
        if self.cleaned_data.get('honeypot'):
            raise ValidationError('Haha, you trapped into the honeypot.')
        return self.cleaned_data['honeypot']

    def clean(self):
        if self.errors:
            raise ValidationError('Please correct the errors below.')
コード例 #11
0
    def __init__(self, request=None, *args, **kwargs):
        """Initialize form, including captcha question and expected answer."""
        super(CaptchaAuthenticationForm, self).__init__(*args, **kwargs)

        # get previous expected answer before generating new one
        self.captcha_answer = request.session.get(CAPTCHA_SESSION_KEY)

        # only add the captcha field if this request hit the rate limit
        if getattr(request, "limited", False):
            a, b = random.randint(1, 9), random.randint(1, 9)
            # avoid negative answers
            if b > a:
                a, b = b, a
            opname, op = random.choice(OPERATORS.items())

            # store the expected answer in the session
            request.session[CAPTCHA_SESSION_KEY] = op(a, b)

            self.fields["captcha"] = forms.IntegerField(
                widget=forms.TextInput,
                required=False,
                label=u"What is {0} {1} {2}?".format(a, opname, b),
            )
コード例 #12
0
ファイル: forms.py プロジェクト: BenjCherpas/balafon
class SearchNameForm(forms.Form):
    """Save search form"""
    search_id = forms.IntegerField(required=False, widget=forms.HiddenInput())
    name = forms.CharField(required=True, label=_("Name"))
    search_fields = forms.CharField(required=True, widget=forms.HiddenInput())
    
    def clean_name(self):
        """validate name"""
        search_id = self.cleaned_data["search_id"]
        
        name = self.cleaned_data["name"]
        if not name:
            raise ValidationError(_("This field is required"))
        
        queryset = models.Search.objects.filter(name=name)
        if search_id:
            queryset = queryset.exclude(id=search_id)
        if queryset.count() > 0:
            raise ValidationError(_("This name is already used"))
        
        if search_id:
            search = models.Search.objects.get(id=search_id)
            if search.name != name:
                search.name = name
                search.save()
        else:
            search = models.Search(name=name)        
        return search
    
    def clean_search_fields(self):
        """validate search fields"""
        search_fields = self.cleaned_data["search_fields"]
        data = json.loads(search_fields)
        for key in ('csrfmiddlewaretoken', 'excluded', 'name', 'field_choice'):
            data.pop(key, None)
        return data
コード例 #13
0
class BasicForm(forms.Form):
    """
    TODO:--------------------------
    input           TextInput               OK
    inputN          NumberInput             OK
    inputEmail      EmailInput
    textarea        TextInput               OK
    drowpdown       Select                  OK
    drowpdown       SelectMultiple          OK
    checkbox        CheckboxInput
    checkbox2       MultiCheckbox?
    radiobox        RadioSelect
    date            DateInput
    time            TimeInput
    datetime        DateTimeInput
    """

    COLORS_CHOICES = [
        ('blue', 'Blue'),
        ('green', 'Green'),
        ('black', 'Black'),
    ]

    name = forms.CharField(max_length=32, widget=widgets.TextInput())
    year = forms.IntegerField(widget=widgets.NumberInput())
    description = forms.CharField(max_length=32, widget=widgets.Textarea(attrs={'rows': '4'}))
    color = forms.ChoiceField(widget=widgets.Select(), choices=COLORS_CHOICES)
    colors = forms.MultipleChoiceField(widget=widgets.Select(attrs={'multiple': True}), choices=COLORS_CHOICES)
    is_boolean = forms.CharField(max_length=32, widget=widgets.CheckboxInput())
    option = forms.ChoiceField(widget=widgets.RadioSelect(), choices=COLORS_CHOICES)
    is_not_boolean = forms.CharField(max_length=32, widget=widgets.CheckboxInput())
    option_again = forms.CharField(max_length=32, widget=widgets.CheckboxInput())

    def __init__(self, *args, **kwargs):
        super(BasicForm, self).__init__(*args, **kwargs)
        self.fields["year"].initial = 2021
コード例 #14
0
class SelectContactOrEntityForm(forms.Form):
    """Select a contact or entity"""
    object_id = forms.IntegerField(widget=forms.HiddenInput(), required=True)
    object_type = forms.CharField(widget=forms.HiddenInput(), required=True)
    name = forms.CharField(required=True, label=_('Name'))

    def clean_name(self):
        """validation"""
        object_id = self.cleaned_data.get('object_id', '')
        object_type = self.cleaned_data.get('object_type', '')
        object_class = {
            'contact': models.Contact,
            'entity': models.Entity,
        }.get(object_type, None)

        if not object_class:
            raise ValidationError(
                ugettext("Invalid type '{0}'").format(object_type))

        try:
            object_id = int(object_id)
            return object_class.objects.get(id=object_id)
        except (ValueError, object_class.DoesNotExist):
            raise ValidationError(ugettext("Does'nt exist"))
コード例 #15
0
ファイル: entities.py プロジェクト: ljean/balafon
class ChangeContactEntityForm(forms.Form):
    """Switch contact entity form"""
    OPTION_ADD_TO_EXISTING_ENTITY = 1
    OPTION_CREATE_NEW_ENTITY = 2
    OPTION_SWITCH_SINGLE_CONTACT = 3
    OPTION_SWITCH_ENTITY_CONTACT = 4

    OPTION_CHOICES = (
        (0, ""),
        (OPTION_ADD_TO_EXISTING_ENTITY, _("Reassign to an existing entity")),
        (OPTION_CREATE_NEW_ENTITY, _("Create a new entity")),
        (OPTION_SWITCH_SINGLE_CONTACT, _("Switch to single contact")),
        (OPTION_SWITCH_ENTITY_CONTACT, _("Switch to entity contact")),
    )

    option = forms.ChoiceField(label=_("What to do?"))
    entity = forms.IntegerField(
        label=_("Which one?"),
        required=False,
        widget=EntityAutoComplete(
            attrs={
                'placeholder': _('Enter the name of the entity'),
                'size': '50',
                'class': 'colorbox'
            }))

    def __init__(self, contact, *args, **kwargs):
        self.contact = contact
        super(ChangeContactEntityForm, self).__init__(*args, **kwargs)

        if contact.entity.is_single_contact:
            single_contact_choices = (self.OPTION_CREATE_NEW_ENTITY,
                                      self.OPTION_SWITCH_SINGLE_CONTACT)
            choices = [
                choice for choice in self.OPTION_CHOICES
                if choice[0] not in single_contact_choices
            ]
        else:
            choices = [
                choice for choice in self.OPTION_CHOICES
                if choice[0] != self.OPTION_SWITCH_ENTITY_CONTACT
            ]

        self.fields['option'].choices = choices

        self.meth_map = {
            self.OPTION_ADD_TO_EXISTING_ENTITY: self._add_to_existing_entity,
            self.OPTION_CREATE_NEW_ENTITY: self._create_new_entity,
            self.OPTION_SWITCH_SINGLE_CONTACT: self._switch_single_contact,
            self.OPTION_SWITCH_ENTITY_CONTACT: self._switch_entity_contact,
        }

    def clean_option(self):
        """validation"""
        try:
            option = int(self.cleaned_data["option"])
            if option == 0:
                raise ValidationError(
                    ugettext("Please select one of this options"))
            try:
                self.meth_map[option]
            except KeyError:
                raise ValidationError(ugettext("Invalid value"))
        except ValueError:
            raise ValidationError(ugettext("Invalid data"))
        return option

    def clean_entity(self):
        """validation"""
        option = self.cleaned_data.get("option", 0)
        if option != self.OPTION_ADD_TO_EXISTING_ENTITY:
            return None
        else:
            entity_id = self.cleaned_data["entity"]
            try:
                return models.Entity.objects.get(id=entity_id)
            except models.Entity.DoesNotExist:
                raise ValidationError(
                    ugettext("Please select an existing entity"))

    def _add_to_existing_entity(self):
        """add to exsiting entity"""
        old_entity = self.contact.entity
        self.contact.entity = self.cleaned_data["entity"]
        self.contact.save()
        old_entity.save()

    def _create_new_entity(self):
        """create new entity"""
        old_entity = self.contact.entity
        self.contact.entity = models.Entity.objects.create()
        self.contact.save()
        old_entity.save()

    def _switch_single_contact(self):
        """switch to single contact"""
        old_entity = self.contact.entity
        self.contact.entity = models.Entity.objects.create(
            is_single_contact=True,
            name="{0.lastname} {0.firstname}".format(self.contact).lower())
        self.contact.save()
        self.contact.entity.default_contact.delete()
        self.contact.entity.save()
        old_entity.save()

    def _switch_entity_contact(self):
        """switch to entity"""
        self.contact.entity.is_single_contact = False
        self.contact.entity.save()

    def change_entity(self):
        """change entity: call the method corresponding to the choice"""
        option = self.cleaned_data["option"]
        method = self.meth_map[option]
        method()
コード例 #16
0
class AddRelationshipForm(forms.Form):
    """form for adding relationships"""
    relationship_type = forms.IntegerField(label=_("relationship type"))
    contact2 = forms.CharField(label=_("Contact"))

    def __init__(self, contact1, *args, **kwargs):
        super(AddRelationshipForm, self).__init__(*args, **kwargs)

        self.reversed_relation = False
        self.contact1 = contact1

        relationship_types = []
        for relationship_type in models.RelationshipType.objects.all():
            relationship_types.append(
                (relationship_type.id, relationship_type.name))
            if relationship_type.reverse:
                relationship_types.append(
                    (-relationship_type.id, relationship_type.reverse))
        self.fields["relationship_type"].widget = forms.Select(
            choices=relationship_types)

        widget = ContactAutoComplete(
            attrs={
                'placeholder': _('Enter the name of a contact'),
                'size': '50',
                'class': 'colorbox'
            })
        self.fields["contact2"] = forms.CharField(label=_("Contact"),
                                                  widget=widget)

    def clean_relationship_type(self):
        """validate relationship type"""
        try:
            self.reversed_relation = False
            relationship_type = int(self.cleaned_data["relationship_type"])
            if relationship_type < 0:
                self.reversed_relation = True
                relationship_type = -relationship_type
            return models.RelationshipType.objects.get(id=relationship_type)
        except ValueError:
            raise ValidationError(ugettext("Invalid data"))
        except models.RelationshipType.DoesNotExist:
            raise ValidationError(ugettext("Relationship type does not exist"))

    def clean_contact2(self):
        """clean the contacts in relation"""
        try:
            contact2 = int(self.cleaned_data["contact2"])
            return models.Contact.objects.get(id=contact2)
        except ValueError:
            raise ValidationError(ugettext("Invalid data"))
        except models.Contact.DoesNotExist:
            raise ValidationError(ugettext("Contact does not exist"))

    def save(self):
        """save"""
        if self.reversed_relation:
            contact1 = self.cleaned_data["contact2"]
            contact2 = self.contact1
        else:
            contact1 = self.contact1
            contact2 = self.cleaned_data["contact2"]

        relationship_type = self.cleaned_data["relationship_type"]
        return models.Relationship.objects.create(
            contact1=contact1,
            contact2=contact2,
            relationship_type=relationship_type)
コード例 #17
0
 def test_parse_int(self):
     int_field = forms.IntegerField()
     result = int_field.clean('15')
     self.assertEqual(15, result)
     self.assertIsInstance(result, int)
コード例 #18
0
 class IntForm(DjangoForm):
     num = forms.IntegerField(max_value=10)
     other = forms.IntegerField()
     third = forms.IntegerField(min_value=10, max_value=150)
コード例 #19
0
ファイル: forms.py プロジェクト: barthlund/froide
class FoiRequestStatusForm(forms.Form):
    def __init__(self, foirequest, *args, **kwargs):
        super(FoiRequestStatusForm, self).__init__(*args, **kwargs)
        self.foirequest = foirequest
        self.fields['refusal_reason'] = forms.ChoiceField(
            label=_("Refusal Reason"),
            choices=[('', _('No or other reason given'))] +
            (foirequest.law.get_refusal_reason_choices()),
            required=False,
            widget=forms.Select(attrs={'class': 'form-control'}),
            help_text=
            _('When you are (partially) denied access to information, the Public Body should always state the reason.'
              ))

    status = forms.ChoiceField(
        label=_("Status"),
        widget=forms.RadioSelect,
        choices=[
            ('awaiting_response', _('This request is still ongoing.')),
            ('resolved', _('This request is finished.')),
            # ('request_redirected', _('This request has been redirected to a different public body.'))
        ])

    resolution = forms.ChoiceField(
        label=_('Resolution'),
        choices=[('', _('No outcome yet'))] +
        FoiRequest.RESOLUTION_FIELD_CHOICES,
        required=False,
        widget=forms.Select(attrs={'class': 'form-control'}),
        help_text=_(
            'How would you describe the current outcome of this request?'))
    redirected = forms.IntegerField(
        label=_("Redirected to"),
        required=False,
        widget=PublicBodySelect,
        help_text=
        _('If your message is redirected to a different Public Body, please specify the new Public Body'
          ))
    if payment_possible:
        costs = forms.FloatField(
            label=_("Costs"),
            required=False,
            min_value=0.0,
            localize=True,
            widget=PriceInput,
            help_text=
            _('Please specify what the Public Body charges for the information.'
              ))

        def clean_costs(self):
            costs = self.cleaned_data['costs']
            if costs is None:
                return 0.0
            return costs

    def clean(self):
        pk = self.cleaned_data.get('redirected', None)
        status = self.cleaned_data.get('status', None)
        if status == "request_redirected":
            if pk is None:
                raise forms.ValidationError(
                    _("Provide the redirected public body!"))
            try:
                self._redirected_public_body = PublicBody.objects.get(id=pk)
            except PublicBody.DoesNotExist:
                raise forms.ValidationError(_("Invalid value"))
        if status == 'resolved':
            if not self.cleaned_data.get('resolution', ''):
                raise forms.ValidationError(
                    _('Please give a resolution to this request'))

        # if resolution is successful or partially_successful, set status to resolved
        if self.cleaned_data.get('resolution',
                                 '') in ('successful', 'partially_successful'):
            self.cleaned_data['status'] = 'resolved'

        return self.cleaned_data

    def set_status(self):
        data = self.cleaned_data
        status = data['status']
        resolution = data['resolution']
        foirequest = self.foirequest

        message = foirequest.message_needs_status()
        if message:
            message.status = status
            message.save()

        if status == "request_redirected":
            foirequest.due_date = foirequest.law.calculate_due_date()
            foirequest.public_body = self._redirected_public_body
            status = 'awaiting_response'

        foirequest.status = status
        foirequest.resolution = resolution

        foirequest.costs = data['costs']
        if resolution == "refused" or resolution == "partially_successful":
            foirequest.refusal_reason = data['refusal_reason']
        else:
            foirequest.refusal_reason = u""

        foirequest.save()

        status = data.pop("status")
        if status == 'resolved':
            foirequest.status_changed.send(sender=foirequest,
                                           status=resolution,
                                           data=data)
コード例 #20
0
class NewEmailingForm(BsForm):
    """Form for creating a new emailing"""

    subscription_type = forms.IntegerField(label=_("Subscription Type"))
    newsletter = forms.IntegerField(label=_("Newsletter"))
    subject = forms.CharField(
        label=_("Subject"),
        required=False,
        widget=forms.TextInput(
            attrs={'placeholder': _('Subject of the newsletter')}))
    contacts = forms.CharField(widget=forms.HiddenInput())
    lang = forms.CharField(required=False,
                           label=_("Language"),
                           widget=forms.Select(choices=[('', _('Default'))] +
                                               list(settings.LANGUAGES)))
    from_email = forms.CharField(required=False, label=_("Sent from"))

    def __init__(self, *args, **kwargs):
        initial = kwargs.get('initial')
        initial_contacts = ''
        if initial and 'contacts' in initial:
            initial_contacts = ';'.join(
                ['{0}'.format(contact.id) for contact in initial['contacts']])
            initial.pop('contacts')
        super(NewEmailingForm, self).__init__(*args, **kwargs)
        if initial_contacts:
            self.fields['contacts'].initial = initial_contacts

        newsletter_choices = [(0, ugettext('-- New --'))] + [
            (newsletter.id, newsletter.subject)
            for newsletter in Newsletter.objects.all().order_by('-id')
        ]
        self.fields["newsletter"].widget = forms.Select(
            choices=newsletter_choices, attrs={'class': 'form-control'})

        subscription_choices = [
            (subscription.id, subscription.name)
            for subscription in SubscriptionType.objects.all()
        ]
        self.fields["subscription_type"].widget = forms.Select(
            choices=subscription_choices, attrs={'class': 'form-control'})

        if not getattr(settings, 'LANGUAGES',
                       None) or len(settings.LANGUAGES) < 2:
            self.fields["lang"].widget = forms.HiddenInput()
        else:
            language_choices = crm_settings.get_language_choices(
                _("Favorite language of the contact"))
            self.fields["lang"].widget = forms.Select(
                choices=language_choices, attrs={'class': 'form-control'})

        if getattr(settings, 'BALAFON_EMAILING_SENDER_CHOICES', None):
            self.fields['from_email'].widget = forms.Select(
                choices=settings.BALAFON_EMAILING_SENDER_CHOICES,
                attrs={'class': 'form-control'})
        else:
            self.fields['from_email'].widget = forms.HiddenInput()

    def get_contacts(self):
        """get the list of contacts stored by ids"""
        ids = self.cleaned_data["contacts"].split(";")
        return models.Contact.objects.filter(id__in=ids)

    def clean_subject(self):
        """subject validation"""
        newsletter_id = int(self.cleaned_data['newsletter'])
        subject = self.cleaned_data['subject']
        if newsletter_id == 0 and not subject:
            raise ValidationError(
                ugettext("Please enter a subject for the newsletter"))
        return subject

    def clean_subscription_type(self):
        """validation of subscription type. Return the subscription type object"""
        try:
            subscription_type = int(self.cleaned_data['subscription_type'])
            return SubscriptionType.objects.get(id=subscription_type)
        except (ValueError, KeyError, SubscriptionType.DoesNotExist):
            raise ValidationError(
                ugettext("Please select a valid subscription"))