Tôi đang cố gắng viết một ứng dụng nhỏ nhận tệp video và chuyển đổi chúng thành định dạng thống nhất sau khi chúng được tải lên (do đó được thêm vào cơ sở dữ liệu). Tôi đã tìm kiếm trên web giải pháp tốt nhất cho điều này và đã quyết định sử dụng tín hiệu của Django với Celery. Nhưng bây giờ tôi đang cố gắng tạo ra một bằng chứng về khái niệm để xem nó có hoạt động hay không.Django - tín hiệu post_init được gọi trên Model instance save & trước khi dụ được tạo ra. Tại sao?
Tôi đang cố gắng thực hiện phương thức video_repalce()
sau khi video mới đã được tải lên (do đó, một hàng mới đã được thêm vào cơ sở dữ liệu). Nhưng tín hiệu không hoạt động đúng, hoặc tôi không hiểu toàn bộ hệ thống hoạt động như thế nào.
Tôi đang sử dụng Django 1.2.3 với được xác định trước tín hiệu django.db.models.signals.post_init
, mà should be called after a model has been instantiated (do đó, một hàng mới được bổ sung vào cơ sở dữ liệu).
from django.core.files.base import File
from django.db.models.signals import post_init
import os
import os.path
import subprocess
class Project(models.Model):
video = models.FileField(upload_to="projects/videos")
def replace_video(self):
"""Replace original video with an updated one."""
# Video conversion process code goes here,
# resulting in a new external video file.
self.video.delete() # Delete the original video.
self.video.save("newfile.webm", File(open("path/to/newfile.webm") ,"wb"))) # Save the new video instead.
self.save() # Commit everything to database.
os.remove("path/to/newfile.webm") # Remove original video copy after it was commited (copied) into the DB.
# ...
# ...
def handle_new_project(sender, **kwargs):
"""Handels some additional tasks for a new added project. i.e. convert video to uniform format."""
project = kwargs['instance']
project.replace_video()
# Call 'Project.replace_video()' every time a new project is added.
post_init.connect(handle_new_project, sender=Project, dispatch_uid="new_project_added")
Tuy nhiên, post_init được gọi không chỉ khi một trường hợp mô hình mới được tạo ra, mà còn ...:
- Trước khi mô hình được thậm chí khởi tạo. Ý tôi là, nó được gọi khi tôi exeucte máy chủ lần đầu tiên, khi thậm chí không có một hàng dữ liệu duy nhất trong cơ sở dữ liệu (do đó, không có đối tượng Model nào được khởi tạo). Ví dụ của
self.pk
làNone
! - Khi
save()
-ing một mô hình. Đoạn mã trên cũng được thực thi khi tôi nhấnself.save()
.
Thực tế, nó không hoạt động theo tài liệu.
Tôi đang làm gì sai? Hãy nhớ rằng đây là một bằng chứng về khái niệm. Tôi định di chuyển mã đến Celery sau khi tôi thấy mã hoạt động. Tuy nhiên, nếu tín hiệu không hoạt động chính xác, Celery sẽ không trợ giúp - Tín hiệu sẽ luôn bị gửi lại một vài lần bất cứ khi nào tôi save()
hoặc cập nhật video.
Bạn có nghĩ rằng tôi không nên gọi save()
bên trong phương thức replace_video()
? Vậy tôi nên gọi nó ở đâu? Tôi nên chọn tín hiệu nào? post_save
không phải là một lựa chọn tốt bởi vì nó cũng được gọi là bất cứ khi nào tôi nhấn save()
.
Bạn đề cập đến tín hiệu luôn được gửi khi bạn thực thi máy chủ, điều gì sẽ xảy ra nếu bạn chỉ cần mở một vỏ 'manage.py shell' và nhập mô hình? –