Auto deleting model instance

I have this model:

class FileUpload(models.Model):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True,
                              blank=False, on_delete=models.SET_NULL)
    filename = models.CharField(max_length=255)
    upload_datetime = models.DateTimeField()
    expiary_datetime = models.DateTimeField()
    file_content = models.FileField(upload_to='uploads/')

    def __str__(self):
        return self.filename

and I want to delete the object automatically when the file date expires.

You would need to create a scheduled task to do this on a periodic basis. I would suggest writing a custom management command that can be scheduled with cron.
Note that you are also responsible for deleting the file itself as well. Deleting a model having a FileField does not remove the underlying file from the file system.

I used cron, here how I used it:
I wrote a manager for FileUpload model

class FileManager(models.Manager):
     def get_queryset(*args, **kwargs):
        return super().get_queryset(*args, **kwargs).filter(
            expiary_datetime__gt=Now()
        )

then in cron.py:

def delete_expired_files():
    FileUpload._base_manager.filter(expiary_datetime__lte=Now()).delete()

but this line of code:

FileUpload._base_manager.filter(expiary_datetime__lte=Now()).delete()

works from the shell.

Sorry, I guess I wasn’t sufficiently clear.

You need to run this as a custom django-admin management command - see How to create custom django-admin commands | Django documentation | Django

You will run manage.py in your cron job to run this new command you will create.

I couldn’t wrap my head around the issue do you have any example for me>?

I’m not sure what “issue” you’re referring to here.

If you’re looking for example management commands, all the standard ones are in your Django installation.

For example, you have probably run the makemigrations command. That file, makemigrations.py is located in django.core.management.commands. All the standard manage commands are in different directories under django. You can learn a lot by how those various commands are written.

I made management command called ‘delete’
and I used crontab to run the command but won’t run:
here cronjobs in settings.py:

CRONJOBS = [
    ('*/1 * * * *', 'django.core.management.commands', ['delete']),
]

How do you run any management command? (e.g. How do you run ‘makemigrations’?)

by run:
python manage.py makemigrations

so I need crontab to run:
python manage.py delete
every minute?!

If you really need to delete the files every minute, yes.

However, I would find it highly unusual that you would need to do that to that level of granularity. What would be wrong with deleting them once / hour or even once / day?

If you needed to ensure that they weren’t retrieved during the window between when they expire and when they’re deleted, you can modify your model manager to filter queries by expiry time.

And again, don’t forget that deleting the model instance does not delete the actual file. If someone with permission to that file knows the url, they would still be able to retrieve it even if the model instance is deleted.

I added this method to FileUplaod model:

 def delete(self, *args, **kwargs):
        storage, path = self.file_content.storage, self.file_content.path
        super(FileUpload, self).delete(*args, **kwargs)
        storage.delete(path)

and I want to run every minute to check if it’s work or not!!
it didn’t by the way, but when I run : python manage.py crontab run #job_hash it works fine.

There is nothing within Django to run tasks periodically. That’s why this type of task needs an external scheduler - either cron or something like Celery Beats.

Hi,

I followed your steps above. My management command to run everyday was to delete models older than a month.

But cron deamon does not seem to resolve the postgres host.

The same python manage.py <command_name> works perfectly from a terminal but errors out with “could not translate host name “postgres” to address: Temporary failure in name resolution”. Can you please help here

Thanks

I’d need to see the details of the various parts of this.

That would be the cron command being run, your database settings in your settings file, any details about how you’re doing your configuration such as using environment variables, and things like that.

In general, these types of problems are caused because the environment created for commands run by cron are not run in a typical login shell. You don’t have the same environment set by default, and you’re frequently running this as a different user. So the key to finding out where it’s failing is to see where an assumption is being made when you’re running this from your shell that you haven’t accounted for in your cron job.