I have two fields in a model here:
is_active = models.BooleanField(default=False)
active_from = models.DateTimeField(blank=True)
When is_active
is set to True
, I'd like active_from
to be updated to the current datetime.
How do I go about doing this? I'm open to alternatives if there's a cleaner way of doing this with one field as well.
Thanks!
EDIT: I'd like to contain this within the model to keep things encapsulated. This will be part of an API.
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.
Whenever one tries to create an instance of a model either from admin interface or django shell, save() function is run. We can override save function before storing the data in the database to apply some constraint or fill some ready only fields like SlugField.
To create a new instance of a model, instantiate it like any other Python class: class Model (**kwargs) The keyword arguments are the names of the fields you've defined on your model. Note that instantiating a model in no way touches your database; for that, you need to save() .
One way to do it is to define a save()
method on your custom model looking for change in is_active
. There is no easy way to achieve this: you need to manually save the previous state of the value of is_active
by defining a custom __init__
-method. It could look something like this:
class MyModel(models.Model):
is_active = models.BooleanField(default=False)
active_from = models.DateTimeField(blank=True)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__is_active = self.active
def save(self, *args, **kwargs):
if self.is_active and not self.__is_active:
self.active_from = datetime.now()
super().save(*args, **kwargs)
This question has some answers which might help.
Another alternative is the FieldTracker from django-model-utils. I'm going to be using this moving forwards, as it makes more complex manipulation easier during save()
.
When you toggle is_active
update active_from
at the same time.
for example:
def toggle_user_active_and_update(request, *a, **kw):
request.user.is_active = !request.user.is_active
request.user.active_from = datetime.datetime.now()
request.user.save()
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