2013-02-13 15 views
9

Có thể lưu các đối tượng liên quan trước khi đối tượng thực đang được chỉnh sửa trên biểu mẫu quản trị django không?Lưu các đối tượng liên quan trước khi đối tượng thực được chỉnh sửa trên django admin

Ví dụ:

trong models.py

class Parent(model.Model): 
    pass 

class Child(model.Model): 
    parent = models.ForeignKey(Parent) 

@receiver(post_save,sender = Parent) 
def notify_parent_save(sender, instance=None, **kwargs): 
    print "Parent save" 

@receiver(post_save,sender = Child) 
def notify_child_save(sender, instance=None, **kwargs): 
    print "Child saved" 

trong admin.py

class ChildInline(admin.TabularInline): 
    model = Child 
    extra = 1 

class ParentsAdmin(admin.ModelAdmin): 
    inlines = [ChildInline] 

admin.site.register(Parent,ParentsAdmin) 

Bây giờ, trong django quản trị nếu tôi tiết kiệm một đối tượng phụ huynh, nó sẽ ra trên bàn điều khiển.

Parent save 
Child save 

tôi cần điều này xảy ra theo thứ tự revese:

Child save 
Parent save 

Trả lời

9

Sau đây sẽ tiết kiệm được những đứa trẻ đầu tiên: Câu trả lời

class ParentAdmin(admin.ModelAdmin): 
    inlines = [ChildInline] 

    def save_model(self, request, obj, form, change): 
     pass # don't actually save the parent instance 

    def save_formset(self, request, form, formset, change): 
     formset.save() # this will save the children 
     form.instance.save() # form.instance is the parent 
0

Tùy thuộc vào chính xác những gì bạn muốn làm trong tín hiệu của bạn, có thể bạn chỉ cần thay đổi post_save để pre_save cho mô hình trẻ em?

3

ccrisan của mang lại cho tôi đi đúng hướng, nhưng tôi nghĩ rằng có một lỗ hổng liên quan đến tiết kiệm hành vi của trường mà chưa có trong cơ sở dữ liệu. Trong trường hợp này, không thể lưu các đối tượng liên quan trước tiên, bởi vì không có khóa ngoại mà chúng có thể trỏ đến. Đối với tôi, tiện ích mở rộng sau đã thực hiện thủ thuật:

class ParentAdmin(admin.ModelAdmin): 
    inlines = [ChildInline] 

    def save_model(self, request, obj, form, change): 
     if not obj.pk: # call super method if object has no primary key 
      super(ParentAdmin, self).save_model(request, obj, form, change) 
     else: 
      pass # don't actually save the parent instance 

    def save_formset(self, request, form, formset, change): 
     formset.save() # this will save the children 
     form.instance.save() # form.instance is the parent 
5

Tôi gặp vấn đề với câu trả lời trong bài đăng này, vì vậy tôi đã tìm ra câu trả lời ngắn gọn hơn. Tôi đã có một vấn đề bởi vì bằng cách sử dụng django-fsm, các câu trả lời khác ở đây sẽ cố gắng để lưu mô hình nhiều lần (một lần cho mỗi formset) chứ không phải là một lần ở cuối.

def save_model(self, request, obj, form, change): 
    if not obj.pk: # call super method if object has no primary key 
     super(YourAdmin, self).save_model(request, obj, form, change) 
    else: 
     pass # don't actually save the parent instance 

def save_related(self, request, form, formsets, change): 
    form.save_m2m() 
    for formset in formsets: 
     self.save_formset(request, form, formset, change=change) 
    super(YourAdmin, self).save_model(request, form.instance, form, change) 

thiết yếu này chỉ flips thứ tự của save_model và save_related như gọi trong Django ModelAdmin source

+0

không chắc chắn nếu điều này là một phiên bản điều Django, hoặc một điều logic kinh doanh, nhưng đối với Django 1.11 và sử dụng của tôi. đây có vẻ là câu trả lời đúng – ckot