from django import forms from django.forms.utils import ValidationError from .validators import validate_email_nouser from .models import Subscriber class SubscribeForm(forms.ModelForm): class Meta: model = Subscriber fields = ['user'] class NewsletterForm(forms.ModelForm): """ This is the base class for all forms managing subscriptions. """ email_field = forms.EmailField(label='Email Address:', widget=forms.EmailInput(attrs={'placeholder': 'Your email address'})) class Meta: model = Subscriber fields = ('email_field',) def __init__(self, *args, **kwargs): assert 'newsletter' in kwargs, 'No newsletter specified' newsletter = kwargs.pop('newsletter') if 'ip' in kwargs: ip = kwargs['ip'] del kwargs['ip'] else: ip = None super(NewsletterForm, self).__init__(*args, **kwargs) self.instance.newsletter = newsletter if ip: self.instance.ip = ip class SubscribeRequestForm(NewsletterForm): """ Request subscription to the newsletter. Will result in an activation email being sent with a link where one can edit, confirm and activate one's subscription. """ email_field = forms.EmailField( label=("e-mail"), validators=[validate_email_nouser], widget=forms.EmailInput(attrs={'placeholder': 'Your email address'}) ) def clean_email_field(self): data = self.cleaned_data['email_field'] # Check whether we have already been subscribed to try: subscription = Subscriber.objects.get( email_field__exact=data, newsletter=self.instance.newsletter ) if subscription.subscribed and not subscription.unsubscribed: raise ValidationError( "Your e-mail address has already been subscribed to." ) else: self.instance = subscription self.instance = subscription except Subscriber.DoesNotExist: pass return data class UpdateForm(NewsletterForm): """ This form allows one to actually update to or unsubscribe from the newsletter. To do this, a correct activation code is required. """ email_field = forms.EmailField( label=("e-mail"), validators=[validate_email_nouser], disabled=True ) def clean_user_activation_code(self): data = self.cleaned_data['user_activation_code'] if data != self.instance.activation_code: raise ValidationError( ('The validation code supplied by you does not match.') ) return data user_activation_code = forms.CharField( label=("Activation code"), max_length=40 )