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

爷,独闯天下 提交于 2021-02-08 10:40:28

问题


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)

回答1:


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()



回答2:


You could use a property for this use case and calculate that on the fly.

@property
def expired(self):
   # calculate here if its still valid


来源:https://stackoverflow.com/questions/57114123/how-can-i-add-an-expiration-date-function-on-a-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!