Reputation: 912
I am trying to set a parameter for a boolean from True to false after a time frame.
For my limited knowledge in Python and Django, I am trying to learn the concept and the logic so that I can apply it in different other places in the project.
here is the Models.py
class Coupon(models.Model):
code = models.CharField(max_length=15, unique=True)
valid_from = models.DateTimeField(blank=True, null=True)
valid_to = models.DateTimeField(blank=True, null=True)
active = models.BooleanField(default=True)
How do set that when the time frame is after valid_to
the Active=status becomes False
here is the views.py
class AddCouponView(View):
def post(self, *args, **kwargs):
now = timezone.now()
form = CouponForm(self.request.POST or None)
if form.is_valid():
try:
code = form.cleaned_data.get('code')
order = Order.objects.get(
user=self.request.user, ordered=False)
coupon = Coupon.objects.filter(code__iexact=code, valid_from__lte=now, valid_to__gte=now).exclude(
order__user=self.request.user, max_value__lte=F('used')).first()
if not coupon:
messages.error(self.request, 'You can\'t use same coupon again, or coupon does not exist')
return redirect('core:checkout')
else:
try:
coupon.used += 1
coupon.save()
order.coupon = coupon
order.save()
messages.success(self.request, "Successfully added coupon")
except:
messages.info(self.request, "Max level exceeded for coupon")
return redirect('core:checkout')
except ObjectDoesNotExist:
messages.info(self.request, "You do not have an active order")
return redirect('core:checkout')
Upvotes: 1
Views: 610
Reputation: 2915
I'm going to offer a few answers here, from the "easiest" (which also has the most downsides wrt reliability, timeliness of execution, and such), to a much heavier solution that probably goes beyond your needs; only you know where to strike that balance for a given project.
One solution would to override the save()
method to add logic checking whether the coupon has expired; this is probably insufficient as coupons are likely rarely saved after creation, and could easily sit in the wrong state for an unacceptable amount of time.
A more flexible solution (without adding dependencies) would be to write a management command to check coupon expiration and invalidate any found expired, and add it to the system cron
. That still has some drawbacks; if the cron runs every hour, coupons could be live for an hour longer than intended. Also cron lives completely apart from your application and if you're not already using it for other tasks, it may be hard to incorporate checking a separate set of logs, etc. into your maintenance/workflow.
The next step up in reliability may be your Goldilocks solution: Django-Cron lets you schedule jobs similarly to cron
but handles execution, result tracking, logging, etc. within your existing Django app.
Most heavy, and overkill for many projects, but reliable and flexible enough for just about anything, is using django-celery-beat. This requires Celery and so it's much more work to setup and maintain than is necessary for personal projects. But it's scalable, very flexible, etc.
Upvotes: 0
Reputation: 9899
One option is to make active
dynamic by changing it to a property, e.g.
class Coupon(models.Model):
code = models.CharField(max_length=15, unique=True)
valid_from = models.DateTimeField(blank=True, null=True)
valid_to = models.DateTimeField(blank=True, null=True)
@property
def active(self):
return self.valid_to >= timezone.now()
The downside is you won't be able to use active
in filters, see Filter by property.
Upvotes: 2