3

我正在编写的 Django 项目中的一个功能是发送时事通讯。我有一个模型Newsletter和一个函数,send_newsletter我已经注册了它来收听Newsletter's 的post_save信号。当通过管理界面保存时事通讯对象时,send_newsletter检查是否created为 True,如果是,则它实际发送邮件。

但是,出于显而易见的原因,编辑已经发送的时事通讯没有多大意义。有没有办法Newsletter在保存对象后将其设为只读?

编辑:

我知道我可以重写save对象的方法来引发错误,或者如果对象存在则什么都不做。但是,我没有看到这样做的意义。至于前者,我不知道在哪里捕获该错误以及如何向用户传达对象未保存的事实。至于后者,给用户错误的反馈(管理界面说保存成功)似乎不是一件好事。

我真正想要的是允许用户使用 Admin 界面编写时事通讯并发送,然后浏览已经发送的时事通讯。我希望管理界面在不可编辑的输入框中显示已发送时事通讯的数据,而无需“保存”按钮。或者,我希望“保存”按钮处于非活动状态。

4

4 回答 4

9

save您可以在模型的方法中检查它是创建还是更新:

def save(self, *args, **kwargs):
    if self.pk:
        raise StandardError('Can\'t modify bla bla bla.')
    super(Payment, self).save(*args, **kwargs)

如果您尝试保存现有对象,上面的代码将引发异常。以前没有持久化的对象没有设置它们的主键。

于 2009-01-21T19:29:25.670 回答
1

推荐阅读: Django Book 第 17 章中的The Zen of Admin 。

摘要:管理员不是为您尝试做的事情而设计的:(

然而,这本书的 1.0 版本只涵盖了 Django 0.96,此后好事不断。

在 Django 1.0 中,管理站点更加可定制。由于我自己没有自定义管理员,我必须根据文档进行猜测,但我会说覆盖模型表单是你最好的选择。

于 2009-02-10T08:57:23.800 回答
0

您可以轻松做的就是将所有字段设为只读:

class MyModelAdmin(ModelAdmin):
    form = ...
    def get_readonly_fields(self, request, obj=None):
        if obj:
            return MyModelAdmin.form.Meta.fields
        else: # This is an addition
            return []

至于让保存消失,如果

  1. has_change_permission即使显示表单,返回 False 也不会禁用
  2. 负责呈现管理表单控件(admin_modify.submit_row模板标签)的代码片段不会show_save=True无条件使用。

无论如何,使那个人不被渲染的一种方法:

  1. 使用正确的逻辑创建 has_change_permission 的替代版本:

    class NoSaveModelAdminMixin(object):
        def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
            response = super(NoSaveModelAdmin, self).render_change_form(request, context, add, change,form_url, obj)
            response.context_data["has_change_permission"] = self.has_real_change_permission(request, obj)
        def has_real_change_permission(self, request, obj):
            return obj==None
        def change_view(self, request, object_id, extra_context=None):
            obj = self.get_object(request, unquote(object_id))
            if not self.has_real_change_permission(request, obj) and request.method == 'POST':
                raise PermissionDenied 
            return super(NoSaveModelAdmin, self).change_view(request, object_id, extra_context=extra_context)
    
  2. 覆盖与此类似的 submit_row 模板标签:

    @admin_modify.register.inclusion_tag('admin/submit_line.html', takes_context=True)
    def submit_row(context):
        ...
            'show_save': context['has_change_permission']
        ...
    
    admin_modify.submit_row = submit_row
    
于 2014-01-15T19:58:53.393 回答
0

在你的 amdin.py 中使用 readonlyadmin。列出你想要只读的所有字段。创建对象后你不能编辑它们

使用链接

http://www.djangosnippets.org/snippets/937/

复制文件,然后导入你的 admin.py 并使用它

于 2010-03-19T14:00:41.443 回答