简体   繁体   中英

How to pass an object between views in Django

I have the following model for my students to upload their tasks to an application that I am creating, but I have a problem, I need to pass an instance of the model between views, but since it is not serializable, I can not save it in a session attribute. Keep in mind that in one view I create the object without saving it in the database and in the other I perform operations with the object and finally I save it. Any idea how I can do this?

from gdstorage.storage import GoogleDriveStorage

gd_storage = GoogleDriveStorage()

class Homework(models.Model):
    code = models.AutoField(primary_key=True)
    student = models.ForeignKey('Student', on_delete=models.PROTECT)
    title = models.CharField(unique=True, max_length=100)
    attached_file = models.FileField(upload_to='files/homeworks/', validators=[validate_file_size], storage=gd_storage)

The only way to keep "state" between views is to save to the database (or other permanent storage). That's what the session does for you.

If you can't serialise to save in the session, then you have no alternative but to save a temporary object to the database. You could mark it as temporary and add a timestamp. And in the next view mark it as committed. And if needed clean up once in a while, removing old temporary objects.

To remove the associated file with old temporary objects, you can add a signal handler for the post_delete signal:

from django.core.files.storage import default_storage

@receiver(post_delete, sender=Homework)
def remove_file(sender, instance, **kwargs)
    path = instance.attached_file.name
    if path:
        default_storage.delete(path)

As @dirkgroten says, you can add an additional field to your model that is called status and by default assign it the value of temporary. In addition to this you can review the package code .

Finally to delete a file in Google Drive as a storage backend is very simple. Use the following

gd_storage.delete(name_file)

So change in the code of @dirkgroten

from django.core.files.storage import default_storage

@receiver (post_delete, sender=Homework)
def remove_file (sender, instance, **kwargs):
    if instance.attached_file is not None:
        gd_storage.delete(instance.attached_file.name)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM