Я хочу генерировать коды ваучеров с ограниченным использованием не более 3-х раз без привязки к пользователю.
views.py:
class ApplyFormView(FormView):
template_name = 'vouchers/apply.html'
model = Voucher
form_class = VoucherApplyForm
def get_success_url(self):
voucher = get_object_or_404(Voucher, pk=self.kwargs['voucher_id'])
discount_value = voucher.value
discount_type = voucher.get_type_display()
messages.add_message(self.request, messages.INFO,
"Congratulations! You've successfully redeemed %s"
" %s off the selected item(s)." % (
discount_value,
discount_type,
))
return reverse('vouchers:apply', kwargs={'voucher_id': self.kwargs['voucher_id']})
def form_valid(self, form):
self.code = self.cleaned_data['code']
form.apply_voucher()
return super(ApplyFormView, self).form_valid(form)
class VoucherDetailView(generic.DetailView):
template_name = 'vouchers/detail.html'
model = Voucher
def get_context_data(self, **kwargs):
context = super(VoucherDetailView, self).get_context_data(**kwargs)
context['redemption_form'] = VoucherApplyForm(initial={'voucher':self.object})
return context
def redeem(request, voucher_id):
voucher = get_object_or_404(Voucher, pk=voucher_id)
try:
redeemed_voucher = voucher.redemption.get(pk=request.POST['voucher'])
except (KeyError, Voucher.DoesNotExist):
return render(request, 'vouchers/detail.html', {
'voucher': voucher,
'error_message': "Voucher is invalid.",
})
else:
redeemed_voucher.redemption += 1
redeemed_voucher.save()
return HttpResponseRedirect(reverse('vouchers:apply', args=(voucher.id,)))
urls.py:
from django.urls import path
from . import views
app_name = 'vouchers'
urlpatterns = [
path('<int:pk>/', views.VoucherDetailView.as_view(), name='detail'),
path('<int:voucher_id>/apply/', views.ApplyFormView.as_view(), name='apply'),
path('<int:voucher_id>/redeem/', views.redeem, name='redeem'),
]
models.py:
class Voucher(models.Model):
code = models.CharField(max_length=30, unique=True)
valid_from = models.DateTimeField()
valid_to = models.DateTimeField()
value = models.IntegerField(default=10)
VOUCHER_TYPES = ((0, 'money-based discount, in RM,'), (1, 'percent'))
type = models.SmallIntegerField(("Type"), choices=VOUCHER_TYPES, default=0)
usage_limit = models.PositiveIntegerField(("Usage limit"), default=3)
active = models.BooleanField()
def __str__(self):
return self.code
@property
def due_to_expire(self):
now = timezone.now()
return now <= self.valid_to <= now + datetime.timedelta(days=5)
@property
def expired(self):
now = timezone.now()
return self.valid_to < now
@property
def is_redeemed(self):
return self.redemption.count() > self.usage_limit and self.usage_limit is not 0
class Redeem(models.Model):
voucher = models.ForeignKey(Voucher, on_delete=models.CASCADE)
redemption = models.PositiveIntegerField(default=0)
def __str__(self):
return self.voucher
Метод get_success_url()
класса ApplyFormView
, похоже, был переопределен методом redeem()
в views.py. Следовательно, запуск URL-адреса приводил только к пустой странице, а не к отображению сообщения об успехе, хотя сообщение об ошибке также не отображалось.
Кроме того, URL FormView
принимает все введенные коды ваучеров, включая те, которые не были указаны на локальном хосте администратора. Могу ли я знать, почему это так? И мне было интересно, как это решить.
Ваша помощь очень ценится. Спасибо!