开发者

Django: How to manipulate a Model object before adding it to DB?

In Python-Django, I've got a Model with a FileField member in it. This member stores video files.

I'd like to "interfere" with the standard "add model row/object/instance" proecdure of Django, and manipulate each开发者_运维知识库 video I'm adding, before actually committing or adding it to database.

The manipulation is to convert the video to a specific uniform format. Thus, all added videos will eventually be stored in the same format (WebM).

How can I do that? I've looked into Django's custom managers, but I don't think that's what I'm looking for.

Thanks. :)


You can either override save() or use signals.

However, converting the video will take a lot of time. It is probably not a good idea to do that synchronously in your web request. A common approach is to offload the work to a task queue. Have a look at Celery for that.


I am actually doing this very same thing. You don't want to process the video file on the same request as it comes in on for several reasons:

1) You will hang the user on a non-responsive page for a long time, possibly timing them out and wondering if it worked. 2) And if they go to see if it uploaded - it still hasn't finished and saved in the DB (non-consistent) they'll think it is broken.

You want to initially save the record and file on your server. Mark it as needs-to-be-worked-on. And fire off a celery task that will do that work and update that flag when it is complete. I am actually doing this very same thing with zencoder for a project I am working on right now. It works wonderfully.

Celery: http://pypi.python.org/pypi/django-celery Ghettoq (for local): http://pypi.python.org/pypi/ghettoq


Or you can use django signals to trigger events when items are about to be, or have been, saved to the database.

Specifically, you use the Signal.connect() method to connect the signal handler you want to launch, for example pre_save, post_save, pre_delete, post_delete etc.

In order to set things up:

signals.py:

from django.db.models.signals import *

def entry_action_post_save(sender, instance, **kwargs):
    # what do we want to do here?
    pass

post_save.connect    (entry_action_post_save,        sender=Entry)

Where for me, Entry is a models.Model derived class.

This blog also covers an alternative way of setting it up using the dispatcher in models.py.

Note that since you are considering video encoding here, you might not want to actually re-encode the video inside these methods, otherwise your request will take forever to complete. A better method would be to check encoding, and have the model have a status field for webM or notwebm. Then pass off your encoding task elsewhere and do not display the video (Videos.objects.filter(format='webm') until it is complete.


You can just override the save() method on your model. See the documentation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜