【问题标题】:Django admin - Duplicate an item under a NestedModelAdminDjango admin - 在 NestedModelAdmin 下复制一个项目
【发布时间】:2023-04-02 17:44:01
【问题描述】:

这个问题与this question直接相关。我可以在带有NestedModelAdmin 的对象上添加“save_as = True”字段吗?如果是这样,我需要做些什么来让它正确复制/另存为新的吗?

我将该字段添加到我的管理模型中,这会更改我的按钮,但是当我单击“另存为新”按钮时,它会将同一按钮中的文本更改为“保存并添加另一个”。之后我单击的任何内容(“保存”、“保存并继续编辑”或“保存并添加另一个”)都会返回此错误:

Exception Type: ValidationError
Exception Value:    
[u"'' value must be an integer."]

我能够将“save_as”字段添加到具有admin.ModelAdmin 的不同对象中,并且它成功地复制了一个对象。我尝试实现this question/answer 中看到的代码,但我得到了同样的错误。我浏览了文档(至少我能理解一点),但找不到任何有用的东西。这个字段是不能添加到 NestedModelAdmin 的吗?任何正确方向的指示都会有很大的帮助。

编辑:

不确定这是否有帮助,但这是我的 admin.py 文件中涉及的元素的一部分代码。

class NestedChoiceInline(NestedStackedInline):
    model = Choice
    form = ChoiceInlineForm
    extra = 1
    fk_name = 'question'


class QuestionInline(NestedStackedInline):
    model = Question
    form = QuestionInlineForm
    extra = 1
    fk_name = 'quiz'
    inlines = [NestedChoiceInline]
    exclude = ['order', ]


class QuizAdmin(NestedModelAdmin):
    model = Quiz
    form = QuizForm
    inlines = [QuestionInline]
    list_display = ('name', 'quiz_start_date',
                    'quiz_end_date')
    save_as = True

    # From another answer that I think I need to do to replicate my object 
    # and anything that has a key to it, but I'm not sure
    def save_model(self, request, obj, form, change):
        if '_saveasnew' in request.POST:
            original_pk = resolve(request.path).args[0]
            original_obj = obj._meta.concrete_model.objects.get(id=original_pk)

            for prop, value in vars(original_obj).iteritems():
                if isinstance(getattr(original_obj, prop), FieldFile):
                    setattr(obj,prop,getattr(original_obj, prop))
        obj.save()

我很确定我了解 save_model 方法的作用,但我不确定我可能需要自定义哪些部分才能正确分配/复制所有内容。

【问题讨论】:

  • 我不完全理解您的问题,但错误消息表明您正在传递一个对象(或一个空字符串)而不是 django 期望的 object.id。你能添加一个更大的代码示例来解释这个问题吗?
  • 是的。让我试着为你隔离一些我的代码。

标签: python django django-models django-admin


【解决方案1】:

我决定使用save_as = True 标志,而只是使用 deepcopy 创建我自己的自定义方法。我不确定copy 是否会与deepcopy 完全相同,但deepcopy 确实想要我需要。

from copy import deepcopy

def duplicate_quiz(modeladmin, request, queryset):
    for quiz in queryset:
        new_obj = deepcopy(quiz)
        new_obj.id = None
        new_obj.save()

        for question in quiz.questions.all():
            question_copy = deepcopy(question)
            question_copy.id = None
            question_copy.save()
            new_obj.questions.add(question_copy)

            for choice in question.choices.all():
                choice_copy = deepcopy(choice)
                choice_copy.id = None
                choice_copy.save()
                question_copy.choices.add(choice_copy)

        new_obj.save()

duplicate_quiz.short_description = "Duplicate Selected Quizzes"

class QuizAdmin(NestedModelAdmin):
    model = Quiz
    form = QuizForm
    inlines = [QuestionInline, DoubleDownQuestionInline]
    list_display = ('name', 'quiz_start_date',
                    'quiz_end_date')
    actions = [duplicate_quiz]

admin.site.register(Quiz, QuizAdmin)

不是我最喜欢的,但它有效。

【讨论】:

    猜你喜欢
    • 2017-06-26
    • 1970-01-01
    • 2017-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 2014-04-20
    • 2013-08-31
    相关资源
    最近更新 更多