From 0248bdf6d110e26d0b5c0057e953f48681068798 Mon Sep 17 00:00:00 2001 From: Skia Date: Thu, 7 Jul 2016 00:52:30 +0200 Subject: [PATCH] Update SubscriptionForm to allow creating user on the fly --- core/models.py | 2 +- subscription/models.py | 17 +++++++++++++---- subscription/views.py | 40 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/core/models.py b/core/models.py index 839ce9b0..88240a66 100644 --- a/core/models.py +++ b/core/models.py @@ -119,7 +119,7 @@ class User(AbstractBaseUser, PermissionsMixin): return reverse('core:user_profile', kwargs={'user_id': self.pk}) def __str__(self): - return self.username + return "User: " + self.username def to_dict(self): return self.__dict__ diff --git a/subscription/models.py b/subscription/models.py index 63aa052a..38b0ad9b 100644 --- a/subscription/models.py +++ b/subscription/models.py @@ -41,9 +41,14 @@ class Subscription(models.Model): ) def clean(self): - for s in Subscription.objects.filter(member=self.member).exclude(pk=self.pk).all(): - if s.is_valid_now(): - raise ValidationError(_('You can not subscribe many time for the same period')) + try: + for s in Subscription.objects.filter(member=self.member).exclude(pk=self.pk).all(): + if s.is_valid_now(): + raise ValidationError(_("You can not subscribe many time for the same period")) + except: # This should not happen, because the form should have handled the data before, but sadly, it still + # calls the model validation :'( + # TODO see SubscriptionForm's clean method + raise ValidationError(_("You are trying to create a subscription without member")) class Meta: ordering = ['subscription_start',] @@ -52,7 +57,11 @@ class Subscription(models.Model): return reverse('core:user_profile', kwargs={'user_id': self.member.pk}) def __str__(self): - return self.member.username+' - '+str(self.pk) + if hasattr(self, "member") and self.member is not None: + return self.member.username+' - '+str(self.pk) + else: + return 'No user - '+str(self.pk) + @staticmethod def compute_start(d=date.today()): diff --git a/subscription/views.py b/subscription/views.py index 4aa96c98..b7f4fbc8 100644 --- a/subscription/views.py +++ b/subscription/views.py @@ -1,7 +1,9 @@ from django.shortcuts import render from django.views.generic.edit import UpdateView, CreateView from django.views.generic.base import View -from django.core.exceptions import PermissionDenied +from django.utils.translation import ugettext_lazy as _ +from django.core.exceptions import PermissionDenied, ValidationError +from django.db import IntegrityError from django import forms from django.forms import Select from django.conf import settings @@ -19,6 +21,41 @@ class SubscriptionForm(forms.ModelForm): model = Subscription fields = ['member', 'subscription_type', 'payment_method'] + def __init__(self, *args, **kwargs): + super(SubscriptionForm, self).__init__(*args, **kwargs) + # Add fields to allow basic user creation + self.fields['last_name'] = forms.CharField(max_length=User._meta.get_field('last_name').max_length) + self.fields['first_name'] = forms.CharField(max_length=User._meta.get_field('first_name').max_length) + self.fields['email'] = forms.EmailField() + self.fields.move_to_end('subscription_type') + self.fields.move_to_end('payment_method') + + def clean(self): + cleaned_data = super(SubscriptionForm, self).clean() + if (cleaned_data.get("member") is None + and "last_name" not in self.errors.as_data() + and "first_name" not in self.errors.as_data() + and "email" not in self.errors.as_data()): + self.errors.pop("member", None) + if Subscriber.objects.filter(email=cleaned_data.get("email")).first() is not None: + self.add_error("email", ValidationError(_("A user with that email address already exists"))) + else: + u = Subscriber(last_name = self.cleaned_data.get("last_name"), + first_name = self.cleaned_data.get("first_name"), + email = self.cleaned_data.get("email")) + u.generate_username() + u.save() + cleaned_data["member"] = u + elif cleaned_data.get("member") is not None: + self.errors.pop("last_name", None) + self.errors.pop("first_name", None) + self.errors.pop("email", None) + if cleaned_data.get("member") is None: + # This should be handled here, but it is done in the Subscription model's clean method + # TODO investigate why! + raise ValidationError(_("You must either choose an existing user or create a new one properly")) + return cleaned_data + class NewSubscription(CanEditMixin, CreateView): # TODO: this must be able to create a new user if needed template_name = 'subscription/subscription.jinja' form_class = SubscriptionForm @@ -35,3 +72,4 @@ class NewSubscription(CanEditMixin, CreateView): # TODO: this must be able to cr start=form.instance.subscription_start ) return super(NewSubscription, self).form_valid(form) +