【问题标题】:How to access request.user from an admin ModelForm clean method?如何从管理员 ModelForm 清理方法访问 request.user?
【发布时间】:2011-01-16 03:57:41
【问题描述】:

我正在管理员 ModelForm 上做一些关于“干净”的事情:

class MyAdminForm(forms.ModelForm):
    def clean(self):
        # Some stuff happens...
        request.user.message_set.create(message="Some stuff happened")

class MyAdmin(admin.ModelAdmin):
    form = MyAdminForm

除了 threadlocals hack - 我如何访问 request.user 来设置消息?我无法将它传递给表单构造函数,因为没有从我的代码中调用。

【问题讨论】:

    标签: django django-admin django-forms


    【解决方案1】:

    如果不将用户传递给表单构造函数,则无法在表单上执行此操作。相反,您可以使用给定请求对象的ModelAdmin.save_model 函数。

    save_model 方法被赋予 HttpRequest,一个模型实例,一个 ModelForm 实例和一个布尔值 基于是添加还是 改变对象。在这里你可以做 任何保存前或保存后的操作。

    http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_model

    编辑: 由于您想将逻辑/消息放在 clean 函数中,您可以执行以下操作:

    class MyAdminForm(forms.ModelForm):
        user_messages = []
        def clean(self):
            # Some stuff happens...
            user_messages.append("Some stuff happened")
    
    class MyAdmin(admin.ModelAdmin):
        form = MyAdminForm
        def save_model(self, request, obj, form, change):
            for message in form.user_messages:
                request.user.message_set.create(message=message)
    

    很晚的编辑:

    user.message_set 在 Django 1.4 中被设置为弃用。您应该改用ModelAdmin.message_userhttps://docs.djangoproject.com/en/1.3/ref/contrib/admin/#django.contrib.admin.ModelAdmin.message_user

    【讨论】:

    • 嗯。该消息取决于一些验证逻辑,因此使用 ModelForm clean() 方法更有意义。如果我把它移到 ModelAdmin save_model() 我将不得不写一些混乱的逻辑只是为了发送消息!
    • 我将 user_messages 移到表单的 init 中并添加了 self.到 'user_messages.append' 行,这是一种享受!谢谢。
    • 将 user_messages 添加为类变量对我来说是个问题,因为消息会累积。我通过在 ModelAdmin def get_form(self, request, obj=None, **kwargs): form = super(ResortAdmin, self).get_form(request, obj, **kwargs) form.user_messages = [] return form 的 get_form 中添加 user_messages 来解决它,是的,我需要在 user_messages.append() 调用之前添加 self
    • 哦,记得打电话给super(MyAdmin, self).save_model(request, obj, form, change)
    【解决方案2】:

    你必须在构造函数中显式传递它,这不是一件事,通常是这样做的。

    您确定要将这些内容放入表单中吗?你到底想在那里做什么?提高ValidationError还不够吗?

    【讨论】:

    • 如前所述,构造函数不在我的代码中 - 它在 contrib.admin 中。我要发送的消息不是错误。这是保存表单影响系统其他部分时的通知。
    • 但这很奇怪 - 你怎么能确定你应该在实际保存表单中的对象之前发送消息?清理和保存之间可能会发生许多不同的事情。
    • 请记住,我们正在讨论管理员更改视图,在清理和保存之间可能会发生什么?
    • 其他清理可能会引发 ValidationError。
    猜你喜欢
    • 2013-07-20
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 2019-01-06
    相关资源
    最近更新 更多