2016-11-08 65 views
0

所以我想贖回我在後端創建的優惠券,並且在我的models.py中遇到錯誤我正在使用django-coupons包,它有很少的文檔,我是掙扎了一下。請幫忙!'QueryDict'對象沒有屬性'用戶'

回溯:

Traceback (most recent call last): 
    File "/Users/krippee/Documents/Projects/lularippee/env/lib/python3.5/site-packages/django/core/handlers/exception.py", line 39, in inner 
    response = get_response(request) 
    File "/Users/krippee/Documents/Projects/lularippee/env/lib/python3.5/site-packages/django/core/handlers/base.py", line 187, in _get_response 
    response = self.process_exception_by_middleware(e, request) 
    File "/Users/krippee/Documents/Projects/lularippee/env/lib/python3.5/site-packages/django/core/handlers/base.py", line 185, in _get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs) 
    File "/Users/krippee/Documents/Projects/lularippee/main/views.py", line 198, in gift_card 
    Coupon.redeem(request.POST) 
    File "/Users/krippee/Documents/Projects/lularippee/coupons/models.py", line 124, in redeem 
    coupon_user = self.users.get(user=user) 
AttributeError: 'QueryDict' object has no attribute 'users' 

views.py

def gift_card(request): 

    user = request.user 

    if request.user.is_authenticated: 
     edit_profile = EditProfileForm(user=user) 
     redeem = CouponForm() 
     if request.method == 'POST': 
      edit_profile = EditProfileForm(request.POST, user=user) 
      redeem = CouponForm(request.POST, user=user) 
      if redeem.is_valid(): 
       Coupon.redeem(request.POST) 
      else: 
       pass 
      return render(request, 'main/profile.html', {'edit_profile': edit_profile, 'redeem': redeem}) 

     return render(request, 'main/profile.html', {'edit_profile': edit_profile, 'redeem': redeem}) 
    else: 
     return redirect('/') 

forms.py

class CouponForm(forms.Form): 
    code = forms.CharField(required=True, 
          label=_("code"), 
          widget=forms.TextInput 
          (attrs={'placeholder':_('Code'), 
            'class': 'text-center'})) 

    def __init__(self, *args, **kwargs): 
     self.user = None 
     self.types = None 
     if 'user' in kwargs: 
      self.user = kwargs['user'] 
      del kwargs['user'] 
     if 'types' in kwargs: 
      self.types = kwargs['types'] 
      del kwargs['types'] 
     super(CouponForm, self).__init__(*args, **kwargs) 

    def clean_code(self): 
     code = self.cleaned_data['code'] 
     try: 
      coupon = Coupon.objects.get(code=code) 
     except Coupon.DoesNotExist: 
      raise forms.ValidationError(_("This code is not valid.")) 
     self.coupon = coupon 

     if self.user is None and coupon.user_limit is not 1: 
      # coupons with can be used only once can be used without tracking the user, otherwise there is no chance 
      # of excluding an unknown user from multiple usages. 
      raise forms.ValidationError(_(
       "The server must provide an user to this form to allow you to use this code. Maybe you need to sign in?" 
      )) 

     if coupon.is_redeemed: 
      raise forms.ValidationError(_("This code has already been used.")) 

     try: # check if there is a user bound coupon existing 
      user_coupon = coupon.users.get(user=self.user) 
      if user_coupon.redeemed_at is not None: 
       raise forms.ValidationError(_("This code has already been used by your account.")) 
     except CouponUser.DoesNotExist: 
      if coupon.user_limit is not 0: # zero means no limit of user count 
       # only user bound coupons left and you don't have one 
       if coupon.user_limit is coupon.users.filter(user__isnull=False).count(): 
        raise forms.ValidationError(_("This code is not valid for your account.")) 
       if coupon.user_limit is coupon.users.filter(redeemed_at__isnull=False).count(): # all coupons redeemed 
        raise forms.ValidationError(_("This code has already been used.")) 
     if self.types is not None and coupon.type not in self.types: 
      raise forms.ValidationError(_("This code is not meant to be used here.")) 
     if coupon.expired(): 
      raise forms.ValidationError(_("This code is expired.")) 
     return code 

models.py

class Coupon(models.Model): 
    value = models.IntegerField(_("Value"), help_text=_("Arbitrary coupon value")) 
    code = models.CharField(
     _("Code"), max_length=30, unique=True, blank=True, 
     help_text=_("Leaving this field empty will generate a random code.")) 
    type = models.CharField(_("Type"), max_length=20, choices=COUPON_TYPES) 
    user_limit = models.PositiveIntegerField(_("User limit"), default=1) 
    created_at = models.DateTimeField(_("Created at"), auto_now_add=True) 
    valid_until = models.DateTimeField(
     _("Valid until"), blank=True, null=True, 
     help_text=_("Leave empty for coupons that never expire")) 
    campaign = models.ForeignKey('Campaign', verbose_name=_("Campaign"), blank=True, null=True, related_name='coupons') 

    objects = CouponManager() 

    class Meta: 
     ordering = ['created_at'] 
     verbose_name = _("Coupon") 
     verbose_name_plural = _("Coupons") 

    def __str__(self): 
     return self.code 

    def redeem(self, user=None): 
     try: 
      coupon_user = self.users.get(user=user) 
     except CouponUser.DoesNotExist: 
      try: # silently fix unbouned or nulled coupon users 
       coupon_user = self.users.get(user__isnull=True) 
       coupon_user.user = user 
      except CouponUser.DoesNotExist: 
       coupon_user = CouponUser(coupon=self, user=user) 
     coupon_user.redeemed_at = timezone.now() 
     coupon_user.save() 
     redeem_done.send(sender=self.__class__, coupon=self) 
+0

對不起你認爲'Coupon'模型具有'users'屬性怎麼辦? –

+0

'def redeem(self,user = None): try: coupon_user = self.users.get(user = user)' – Kerosive

回答

0

您的問題是您正在調用實例方法redeem而不是實例。你還期待user但經過request.POST應該是

if redeem.is_valid(): 
    coupon = redeem.coupon 
    coupon.redeem(request.user) 

代替

if redeem.is_valid(): 
    Coupon.redeem(request.POST) 
+0

這給了我一個CouponForm對象沒有任何屬性'save'錯誤。 – Kerosive

+0

@Kerosive你正在使用'Form',而不是'ModelForm',這就是爲什麼。但是你在'clean_code'中設置'coupon'。所以我們可以使用它。更新了答案。 –

+0

它工作!非常感謝你,先生,你是男人之間的神。 – Kerosive

相關問題