(Django 1.1) Tôi có một mô hình dự án theo dõi các thành viên của nó bằng cách sử dụng trường m2m. Nó trông giống như thế này:Django - Cách lưu dữ liệu m2m qua tín hiệu post_save?
class Project(models.Model):
members = models.ManyToManyField(User)
sales_rep = models.ForeignKey(User)
sales_mgr = models.ForeignKey(User)
project_mgr = models.ForeignKey(User)
... (more FK user fields) ...
Khi dự án được tạo ra, chọn sales_rep
, sales_mgr
, project_mgr
, vv User
s được bổ sung cho các thành viên để làm cho nó dễ dàng hơn để theo dõi các điều khoản của dự án. Cách tiếp cận này đã làm việc rất tốt cho đến nay.
Vấn đề tôi đang giải quyết bây giờ là cách cập nhật tư cách thành viên của dự án khi một trong các trường FK User
được cập nhật qua quản trị viên. Tôi đã thử các giải pháp khác nhau cho vấn đề này, nhưng cách tiếp cận sạch nhất dường như là một tín hiệu post_save
như sau:
def update_members(instance, created, **kwargs):
"""
Signal to update project members
"""
if not created: #Created projects are handled differently
instance.members.clear()
members_list = []
if instance.sales_rep:
members_list.append(instance.sales_rep)
if instance.sales_mgr:
members_list.append(instance.sales_mgr)
if instance.project_mgr:
members_list.append(instance.project_mgr)
for m in members_list:
instance.members.add(m)
signals.post_save.connect(update_members, sender=Project)
Tuy nhiên, Project
vẫn có các thành viên cùng ngay cả khi tôi thay đổi một trong các lĩnh vực thông qua quản trị viên! Tôi đã thành công trong việc cập nhật các thành viên m2m bằng cách sử dụng quan điểm của riêng tôi trong các dự án khác, nhưng tôi chưa bao giờ phải làm cho nó chơi tốt đẹp với quản trị viên.
Có cách tiếp cận nào khác mà tôi nên thực hiện ngoài tín hiệu post_save để cập nhật tư cách thành viên không? Cảm ơn trước sự giúp đỡ của bạn!
UPDATE:
Chỉ cần làm rõ, tín hiệu post_save hoạt động chính xác khi tôi tiết kiệm hình thức riêng của tôi ở cuối phía trước (thành viên cũ bị loại bỏ, và những người mới được bổ sung). Tuy nhiên, tín hiệu post_save KHÔNG hoạt động chính xác khi tôi lưu dự án thông qua admin (các thành viên vẫn giữ nguyên).
Tôi nghĩ chẩn đoán của Peter Rowell là chính xác trong tình huống này. Nếu tôi xóa trường "thành viên" khỏi biểu mẫu quản trị thì tín hiệu post_save hoạt động chính xác. Khi trường được bao gồm, nó sẽ lưu các thành viên cũ dựa trên các giá trị có trong biểu mẫu tại thời điểm lưu. Không có vấn đề gì thay đổi tôi thực hiện cho các thành viên m2m lĩnh vực khi dự án được lưu (cho dù đó là một tín hiệu hoặc tùy chỉnh lưu phương pháp), nó sẽ luôn luôn được ghi đè bởi các thành viên đã có mặt trong mẫu trước khi lưu. Cảm ơn bạn đã chỉ ra điều đó!
Tôi không biết nếu điều này là vấn đề của bạn, nhưng tôi có một cảm giác ruột mà bạn có thể chạy vào một artifact của cách mã hình thức cập nhật thông tin m2m. Về cơ bản họ lần đầu tiên lưu đối tượng chính, sau đó họ thiết lập các giá trị m2m bằng cách đầu tiên thanh toán bù trừ tất cả chúng, và sau đó đặt chúng dựa trên các giá trị hiện tại * trong biểu mẫu *. Điều này xảy ra * sau * save() trên đối tượng chính, vì vậy bất cứ điều gì bạn làm trong save() hoặc dựa trên tín hiệu 'post_save' được thực hiện lần đầu tiên, và sau đó * undone *. Đây là trong 'django.forms.models.save_instance()'. Sẽ tốt hơn nếu có tín hiệu 'after_form_save'. –
Cảm ơn, Peter! Tôi tin rằng chẩn đoán của bạn là chính xác. Tôi đã cập nhật bài đăng gốc của mình để bao gồm thông tin này. –
Peter đúng. Tôi đã có cùng một vấn đề và tìm thấy một workaround, nhưng nó không phải là gọn gàng như một tín hiệu 'after_form_save': http://stackoverflow.com/questions/3652585/simple-django-form-model-save-question –