Best way to keep track of DurationField in model?

I have a DurationField (time_open_for) in my model as well as a BooleanField (is_open) which keeps track of whether an instance of this model is open or not (defaults to true). The model also has a date_created (DateTimeField). What I wish to happen is for when the time_open_for runs out for the is_open to set itself to False. I know I can do this using logic inside views: something like

if datetime.datetime.now(tz=pytz.UTC) > (date_created + time_open_for):
   model_name.is_open = False
   model_name.save() 

I have been doign this and it works but the problem i’m having is that the view function actually needs to get called in order to close a model (set is_open=False). This means that even though sufficient time may have passed for my model to close it may remain open since a user may not have clicked on something which would have closed it. I was wondering if there might perhaps be some way of enforcing the database itself to periodically call the function independent of user activity so as to check the time constraints and if necessary inactivate those instances whos open_until time has elapsed?

Any help would be kindly appreciated. Perhaps I’ve got the wrong idea of how to approach/use DurationFields in models.

Mike

Yes, you can use Celery with the ETA parameter to schedule a function to be executed later.

But, this is a topic that is just filled with pitfalls.

Not only do you need to handle a “function-to-be-called-later” situation, but you also need to have a way to cancel that function.

For example, Person A does something that opens the model and schedules the automatic close function for later.
If Person A then does something that closes that model, and the Person B opens the model before the “function-to-be-called-later” gets executed, that function could be called before the proper amount of time expires.

Any type of functional “lock” on a model is a Real Problem ™ in a web-based environment, and I suggest you think real hard about finding a different solution for the underlying issue you’re trying to address here.

Ken

Thanks for the advice Ken, I will see if perhaps there might be a better way to approach it then as it seems far more complicated than I had anticipated.

Thinking about it some more, there was one method I’ve seen used that worked reasonably well.

Instead of having an “is_open” field, you have a field “open_until”, and a field with the username of the person who opened it.
If the item is accessed by the person who currently has it open, extend the open_until date appropriately.
When the person closes it, set the open_until field to the current time.
Anyone else needing to access it, can only access it if the open_until field is before the current date, and upon doing so, updates the open_until field along with the username field.

Good suggestion! I made a mock project to implement your suggestion and it worked well, using an ‘open_until’ field and an attatched ‘last_user_accessed’ on the same model as a foreign key to a particular User