保存相关对象的Django管理正在编辑的实际对象之前(Save the related object

2019-07-19 20:04发布

是否可以保存相关对象Django管理形式正在编辑的实际对象之前?

例如:

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

Answer 1:

下面将先救孩子:

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


Answer 2:

我是有在这个职位的答案的问题,所以我想出了一个更简洁的答案。 我有一个问题,因为使用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源



Answer 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


Answer 4:

取决于你究竟想在你的信号做,可你只需要改变的post_save到pre_save为儿童模式?



文章来源: Save the related objects before the actual object being edited on django admin