Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can i add an expiration date function on a model?

i am trying to make a key verification app that when accepted it would create the same app on the user's profile, so i have done everything but i have struggled making the expiration date part, i want the expired boolean become true when the date is expired, but i have no idea on how to implement it

#models.py
    class ProductKey(models.Model):
        product = models.ForeignKey(Product, on_delete=models.CASCADE, 
        unique=False)
        key = models.CharField(max_length=14)
        valid_from = models.DateTimeField(default=timezone.now)
        valid_to = models.DateTimeField()
        expired = models.BooleanField(default=False)
like image 308
rector Avatar asked Nov 30 '25 02:11

rector


1 Answers

Please do not add a database field for this. You will introduce data duplication: if you later set the valid_to, you will have to update expred as well, so the logic would introduce extra challenges.

You can annotate your ProductKey model, such that objects that arise from this have an attribute expired:

from django.db.models import BooleanField, ExpressionWrapper, Q
from django.db.models.functions import Now

ProductKey.objects.annotate(
    expired=ExpressionWrapper(Q(valid_to__lt=Now()), output_field=BooleanField())
)

You can then filter on that property. For example you can retrieve the ProductKeys that are expired with:

ProductKey.objects.annotate(
    expired=ExpressionWrapper(Q(valid_to__lt=Now()), output_field=BooleanField())
).filter(expired=True)

If you need this often, you can annotate this in the manager, like:

class ExpiredManager(models.Manager):

    def get_queryset(self):
        return super().get_queryset().annotate(
            expired=ExpressionWrapper(Q(valid_to__lt=Now()), output_field=BooleanField())
        )

class ProductKey(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, 
    unique=False)
    key = models.CharField(max_length=14)
    valid_from = models.DateTimeField(default=timezone.now)
    valid_to = models.DateTimeField()

    objects = ExpiredManager()
like image 137
Willem Van Onsem Avatar answered Dec 06 '25 07:12

Willem Van Onsem