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?
Use update_fields in save() If you would like to explicitly mention only those columns that you want to be updated, you can do so using the update_fields parameter while calling the save() method. You can also choose to update multiple columns by passing more field names in the update_fields list.
According to documentation, An AutoField is an IntegerField that automatically increments according to available IDs. One usually won't need to use this directly because a primary key field will automatically be added to your model if you don't specify otherwise.
To answer your question, with the new migration introduced in Django 1.7, in order to add a new field to a model you can simply add that field to your model and initialize migrations with ./manage.py makemigrations and then run ./manage.py migrate and the new field will be added to your DB. Save this answer.
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'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With