【问题标题】:overriding save_form in an Admin doesn't work for an inline'd Admin在管理员中覆盖 save_form 不适用于内联管理员
【发布时间】:2011-05-08 09:50:27
【问题描述】:

我重写 save_form 以使用 obj.author = request user 自动填充类申诉中的作者字段。效果很好。但是,出于内联的目的,我使用 obj.status_author = request.user 尝试了同样的事情。不起作用 - 没有输入任何内容并且 sql 执行失败,因为 status_author 是必填字段。

在我的 GrievancesAdmin 中为 obj.author 成功覆盖了 save_form。如果我对 obj.status_author 尝试相同的操作,但在 GrievanceStatusAdmin(内联)中,它在输入中不起作用。

我有以下文件:

models.py

class Grievances(models.Model):
    title = models.CharField(max_length=90)
    author = models.ForeignKey(User, related_name='grievance_author')
    firefighter = models.ForeignKey(User, related_name='firefighter_harmed')
    ...

class GrievanceStatus(models.Model):
    title = models.ForeignKey(Grievances)
    updatetext = models.TextField(blank=True)
    action = models.CharField(max_length=20)
    status_author = models.ForeignKey(User, related_name='grievance_status_author')

forms.py

class UserModelChoiceField(forms.ModelChoiceField):
    """ Override to use full name in ChoiceField """
    def label_from_instance(self, obj):
        return "%s (%s)" % (obj.get_full_name(), obj.username)

class GrievanceForm(forms.ModelForm):
    firefighter = UserModelChoiceField(User.objects.all().order_by('last_name')) 
    class Meta:
        model = Grievances

class GrievanceStatusForm(forms.ModelForm):
    class Meta:
        model = GrievanceStatus
        fields = ('action', 'updatetext', )

admin.py

class GrievanceStatusInline(admin.StackedInline):
    model = GrievanceStatus
    fk_name = 'title'
    form = GrievanceStatusForm
    list_select_related = True

class GrievancesAdmin(admin.ModelAdmin):
    list_display = ('title', 'firefighter',)
    inlines = [ GrievanceStatusInline ]
    form = GrievanceForm

    def save_formset(self, request, form, formset, change):
        ### something is wrong with the following line but i'm not sure what ###
        obj2 = super(GrievancesAdmin, self).save_formset(request, form, formset, change)
        obj2.status_author = request.user
        formset.save()

    def save_form(self, request, form, change):
        obj = super(GrievancesAdmin, self).save_form(request, form, change)
        obj.firefighter = User.objects.get(username__exact=obj.firefighter)
        obj.status_author = request.user
        if not change:
            obj.author = request.user
        obj.date_updated = datetime.datetime.now()
        return obj
admin.site.register(Grievances, GrievancesAdmin)

谢谢!

【问题讨论】:

    标签: django django-models django-admin django-forms


    【解决方案1】:

    对于内联管理员,您可能希望改写 save_formset

    【讨论】:

    • 覆盖内联中的 save_formset?如 -- obj = super(GrievanceStatusInline, self).save_formset(request, form, formset, change) -- 或者在一级 Admin 内?
    • 顶级管理员GrievancesAdmin。这是控制表单保存的内容。
    • 我已将 save_formset 的覆盖添加到顶级管理员 GrievancesAdmin。但它仍然没有处理通过。通过打印语句,我已经弄清楚它挂在哪一行。请参阅上面我编辑的 admin.py 文件和评论。谢谢。
    • save_formset 实际上并没有返回任何内容(contrib/admin/options.py 的第 603 行),因此您突出显示的行实际上是将 obj2 设置为 None
    【解决方案2】:

    您应该尝试以下方法!我试了一下...except 块在那里,因为页面上可能还有其他表单,它们没有 status_author 属性!

    class GrievancesAdmin(admin.ModelAdmin):
    
       def save_formset(self, request, form, formset, change):
           formset.save()
           if not change:
               for f in formset.forms:
                   try:
                       obj = f.instance 
                       obj.status_author = request.user
                       obj.save()
                    except:
                       continue
    

    【讨论】:

    • 谢谢。那行得通,但是无论我是否使用该代码,我最终都将问题缩小到了 GrievanceStatusForm 类中 forms.py 中的“fields = ('action', 'updatetext', )”行。当我指定字段并且不包括我的 status_author(期望它在 save_formset 中得到处理)时,它会因关于 not null 的 sql 错误而崩溃。如果我注释掉 forms.py 中的字段行并让 django 显示模型中所有内容的字段,那么它就可以工作。但这让我的用户改变了作者,我不想这样做。所以我还在寻找我的答案。
    猜你喜欢
    • 2013-04-05
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 2014-05-13
    • 2015-06-21
    • 1970-01-01
    相关资源
    最近更新 更多