2016-11-08 4 views
0

Так что я пытаюсь выкупить купон, который я создал на бэкэнд, и я столкнулся с ошибкой в ​​своем models.py. Я использую пакет django-coupons, который имеет очень небольшую документацию, и я немного борясь с этим. Пожалуйста помоги!Объект QueryDict не имеет атрибутов 'users'

отслеживающий:

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'. Поэтому мы можем использовать это. Обновленный ответ. –

+0

Это сработало! Большое вам спасибо, сэр, вы бог среди мужчин. – Kerosive

Смежные вопросы