Django 管理预览

Django admin preview

我需要在管理 create/edit 页面中有 "Preview" 按钮。 当用户单击此按钮时,应保存表单并重定向到特定 url,用户可以在其中查看有关他刚刚添加或编辑的对象的信息。

所以我有自定义的 ModelAdmin class,我需要内联表单集:

class InboundAdmin(admin.ModelAdmin, ListView):
    model = Inbound
    form = InboundForm
    change_form_template = 'admin/tour/inbound_form.html'
    inlines = [InboundTourDatesInline, InboundProgramInline, InboundFeedbackInline, InboundMedia,
               InboundTourSliderPhotoInline, InboundPriceDynamicsInline]

模板扩展 admin/change_form.html。 此模板有自定义按钮:

<input type="submit" value="{% trans 'Preview' %}" class="default draft-submit" name="_save_as_draft" />

而这个脚本其中:

$('.draft-submit').on('click', function(){
                $.ajax({
                    type: "POST",
                    url: "{% url 'tours:inbound_draft' %}",
                    data: $("#{{ opts.model_name }}_form").serialize()
                });
            });

这是 inbound_draft 视图:

def draft_inbounds(request):
    print('inbounds')
    form = InboundForm(request.POST or None, request.FILES or None)
    if form.is_valid():
        print('is_valid')
        form.save()
        # Here I should return specific url with pk as an attribute.
    print('not_valid')

问题是,当我单击“预览”按钮时,它会保存更改,但会将我重定向回管理员中的 list_view。解决我的问题的正确方法是什么?

当您将按钮设置为 submit 输入时,它会提交表单,从而将您重定向到更改列表。要制作该按钮 "js-only",请更改其类型:

<input type="button" value="{% trans 'Preview' %}" class="default draft-submit" name="_save_as_draft" />

或者您可以阻止通过 JS 提交表单:

$('.draft-submit').on('click', function(event){
    event.preventDefault();
    // the rest of your code
});

我找到了一个很好的解决方案,可以完全解决我的问题。 您只需要覆盖 ModelAdmin class 的 save_model()response_change()response_add() 方法即可。 这是我在 admin.py 文件中的 class:

class InboundAdmin(admin.ModelAdmin, ListView):
    model = Inbound
    form = InboundForm
    change_form_template = 'admin/tour/inbound_form.html'
    inlines = [InboundTourDatesInline, InboundProgramInline, InboundFeedbackInline, InboundMedia,
               InboundTourSliderPhotoInline, InboundPriceDynamicsInline]

def save_model(self, request, obj, form, change):
    if "_draft" in request.POST:
        obj.published = False  # If it is a draft, then post should not be published
    else:
        obj.published = True
    super(InboundAdmin, self).save_model(request, obj, form, change)

def response_change(self, request, obj):
    if "_draft" in request.POST:
        return HttpResponseRedirect(reverse_lazy("tours:inbound_detail", kwargs={'pk': obj.pk}))
    else:
        return super(InboundAdmin, self).response_change(request, obj)

def response_add(self, request, obj, post_url_continue=None):
    if "_draft" in request.POST:
        return HttpResponseRedirect(reverse_lazy("tours:inbound_detail", kwargs={'pk': obj.pk}))
    else:
        return super(InboundAdmin, self).response_add(request, obj, post_url_continue=None)

如果请求包含 "_draft" 然后我重定向到需要的 url,否则它使用默认方法。

在您的模板中,您应该将储蓄按钮添加为草稿:

<input type="submit" value="{% trans 'Save as a draft' %}" class="default draft-submit" name="_draft" />

就这些)