2013-02-13 59 views
9

在django管理員表單上編輯實際對象之前是否可以保存相關對象?在django上編輯實際對象之前保存相關對象admin

例如:

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" 

admin.py

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

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

admin.site.register(Parent,ParentsAdmin) 

現在,Django管理,如果我救一個父對象,它會在控制檯上輸出。

Parent save 
Child save 

我需要這在revese順序發生:根據你究竟想在你的信號做

Child save 
Parent save 

回答

9

下面將先救孩子:

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

,可你只需要改變的post_save到pre_save爲兒童模式?

3

ccrisan的回答使我在正確的軌道上,但我認爲這是關於保存那些尚未存在於數據庫實例的行爲缺陷。在這種情況下,不可能首先保存相關的對象,因爲沒有可以指向的外鍵。對我來說,下面的擴展做的伎倆:

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

我是有在這個職位的答案的問題,所以我想出了一個更簡潔的答案。我遇到了一個問題,因爲使用django-fsm,這裏的其他答案會嘗試多次保存模型(每個表單集一次),而不是最後一次。

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) 

這一基本只是翻轉save_model的順序和save_related如稱爲Django ModelAdmin source

+0

不知道這是一個Django版本的東西,或者業務邏輯的事情,但Django的1.11和我的使用。這似乎是正確的答案 – ckot 2017-12-18 22:23:35