提交表单时更新用户

时间:2014-05-01 21:38:54

标签: python django django-forms django-views

方案是我正在构建一个应用程序供用户提交付款并获得或续订"会员"网站的状态。如果一个匿名人想要创建一个帐户,只需要一个电子邮件和一个密码,但对于成员资格,我们也希望填写User.firstname和User.lastname。我不确定如何最好地将此要求纳入"注册"形成。欢迎任何关于方法或最佳实践的指导。

以下是我使用

的代码
class MembershipType(models.Model):
    """The represents the type of membership that may be offered."""

    active = models.BooleanField(default=True)
    long_name = models.CharField(max_length=255)
    period = models.PositiveIntegerField()  # The number of days the membership is good for
    accounts = models.PositiveSmallIntegerField()  # The number of accounts that it supports
    price = models.DecimalField(max_digits=5,
                                decimal_places=2)

    def __unicode__(self):
        return self.long_name


class Membership(models.Model):

    """Represents an active membership of a user. Both the start_date and
    end_date parameters are inclusive."""

    DEFAULT_DURATION = 365  # the default number of days a membership is active

    start_date = models.DateField(auto_created=True)
    end_date = models.DateField(null=True)
    membership_type = models.ForeignKey(MembershipType)
    referral = models.ForeignKey(User, related_name='membership_referral')

    # Contact Info
    phone = PhoneNumberField()

    # Address Fields
    address_1 = models.CharField(max_length=255)
    address_2 = models.CharField(max_length=255, blank=True)

    city = models.CharField(max_length=64)
    state = USStateField()
    zip_code = USPostalCodeField()

    @property
    def is_active(self):
        return self.end_date >= datetime.date.today()


class MembershipUser(models.Model):
    """Simple relationship that associates a single user to a membership object"""
    user = models.OneToOneField(User)
    membership = models.ForeignKey(Membership)

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        if (self.membership.membership_type.accounts ==
                MembershipUser.objects.filter(membership=self.membership).count()):
            raise NotImplementedError("The Membership %s, already has it's "
                                      "maximum number of accounts associated "
                                      "with it." % self.membership.id)

另外,正如您可能从该代码中看到的那样,我必须支持单个用户购买会员资格的想法,该会员资格可能会用于一个以上的用户。这里的一个用例是#34; Couple"成员资格。

1 个答案:

答案 0 :(得分:0)

我实施它的方式是这样的。它似乎处理好一切,并将预先填写用户的信息。我觉得我应该能够引用用户对象,而不必将其传回,但它可以工作。

models.py

class Membership(models.Model):

    """Represents an active membership of a user. Both the start_date and
    end_date parameters are inclusive."""

    DEFAULT_DURATION = 365  # the default number of days a membership is active

    start_date = models.DateField(auto_created=True)
    end_date = models.DateField(null=True)
    membership_type = models.ForeignKey(MembershipType)
    referral = models.ForeignKey(User, related_name='membership_referral', null=True)

    # Contact Info
    phone = PhoneNumberField()

    # Address Fields
    address_1 = models.CharField(max_length=255)
    address_2 = models.CharField(max_length=255, blank=True)

    city = models.CharField(max_length=64)
    state = USStateField()
    zip_code = USPostalCodeField()

    def save(self, force_insert=False, force_update=False, using=None,
         update_fields=None):
    """Overload the save function to set the start and end date."""
    self.start_date = datetime.date.today()
    self.end_date = (self.start_date +
                     datetime.timedelta(days=self.membership_type.period))
    super().save()

    @property
    def is_active(self):
    return self.end_date >= datetime.date.today()

forms.py

class MembershipForm(ModelForm):
    """The Form shown to users when enrolling or renewing for membership."""

    def __init__(self, *args, **kwargs):
    self.user = kwargs.pop("user", None)

    _fields = ('first_name', 'last_name', 'email',)
    _initial = model_to_dict(self.user, _fields) if self.user is not None else {}

    super(MembershipForm, self).__init__(initial=_initial, *args, **kwargs)
    self.fields.update(fields_for_model(User, _fields))
    self.fields['referral'].required = False

    class Meta:
    model = Membership
    fields = ['membership_type', 'referral', 'phone', 'address_1',
              'address_2', 'city', 'state']

    zip_code = USZipCodeField(max_length=5, required=True)

    def save(self, *args, **kwargs):
    self.user.first_name = self.cleaned_data['first_name']
    self.user.last_name = self.cleaned_data['last_name']
    self.user.email = self.cleaned_data['email']
    self.user.save()
    profile = super(MembershipForm, self).save(*args, **kwargs)
    return profile

views.py

@login_required
def enroll(request):
    template_name = 'enroll.html'

    if request.method == 'POST':
    form = MembershipForm(request.POST, user=request.user)

    if form.is_valid():
        form.save()
        return redirect('/')
    else:
    form = MembershipForm(user=request.user)

    return render(request, template_name, {'form': form})