I have a model and I want to know if it is possible to set a condition that triggers a change in the model field. For example, I have a model
class BillboardTracker(models.Model):
client_name = models.CharField(max_length=400)
entry_date = models.DateTimeField(default=datetime.now)
duration = models.PositiveIntegerField()
expiry_date = models.DateField()
is_expired = models.BooleanField(default=False)
I want to know if it is possible to have a function in the model that makes is_expired equals to True when the expiry date is up. I tried this
def expire(self):
if datetime.now == self.expiry_date:
self.is_expired = True
but it's not working. Is it possible to implement this?
The simplest thing here is not to have an is expired field at all! It's not needed. What you need is a property.
class BillboardTracker(models.Model):
client_name = models.CharField(max_length=400)
entry_date = models.DateTimeField(default=datetime.now)
duration = models.PositiveIntegerField()
expiry_date = models.DateField()
@property
def is_expired(self):
if datetime.now > self.expiry_date:
return True
return False
Remember, you don't have a field in a database, if that field is the same as another field with a simple calculation. This automatically eliminates your head ache of having to flag items as expired.
If you want to find out if an object has expired.
if instance.is_expired == True:
print 'yes, that ones gone'
If you wanted to retrieve a whole set of objects that have expired
BillboardTracker.objects.filter(expiry_date__le=datetime.now())
This is why I mentioned that you don't need to store a field that can be easily calculated.
In most RDBMS a boolean field (such as your is_expired column) cannot be indexed effectively. So that actually means the above query will be faster than a query on that boolean field provided you create an index on the expiry_date field.
You need to make two changes in this function, Firstly use datetime.now() and secondly,
You might want to update your logic like this :
def expire(self):
if datetime.now() >= self.expiry_date:
self.is_expired = True
return True
else:
return False
Because sometimes both the values might not be exactly same but still BillboardTracker need is_expired = True for all previous dates.
And in your views :
def your_view(request):
instance = BillboardTracker.objects.get(id=some_id)
if instance.is_expired() == True:
print 'expired'
else:
print 'fresh'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.