【问题标题】:Is there any way to make the wagtail body field readonly?有没有办法让鹡鸰身体字段只读?
【发布时间】:2019-07-06 07:53:12
【问题描述】:

我正在用 wagtail 开发博客应用程序。

关于博客页面的要点: 作家可以写“标题”、“介绍”和“正文”。 首先,作者可以提交标题。 完成“标题任务”后,作者可以编辑并提交正文。 当作者做标题任务时,作者不能编辑正文字段。 此外,作者在执行正文任务时,作者无法编辑标题字段。

我想动态更改titleFieldbodyField(RichTextField) 的权限,但我不知道该怎么做。

我认为在 wagtail_hooks.py 中编辑关于 @hooks.register("after_edit_page") 的钩子可以解决。 我尝试使用PagePermissionHelperPermissionHelper

【问题讨论】:

    标签: django wagtail


    【解决方案1】:

    提出的解决方案

    • 关于 Customising generated forms 的 Wagtail 文档解释了在编辑/创建新页面时覆盖生成的表单的方法。
    • WagtailAdminPageForm 扩展了 Django ModelForm,您可以进一步扩展它以添加自定义 clean/__init__/save 等方法,以添加您想要的任何逻辑,包括表单的呈现方式和内容在应用保存之前向用户提供错误。
    • Django ModelForm documentation
    • 默认情况下,您在创建表单时无法访问 request 对象,但您可以通过 save 方法获得它,因此可以轻松地在那里执行一些用户基本逻辑。
    • 如果您需要进一步定制,您可以深入了解Wagtail edit handers(搜索源代码),您可以创建自己的编辑处理程序,将请求传递给您的自定义BlogPageForm
    • 注意:如果最终目标是添加一个完整的基于“流程”的页面编辑工作流程,您可能需要查看 Wagtails 的 ModelAdmin 并且基本上只是完全独立于正常页面结构构建博客工作流程和然后重组权限,使博客编辑者无法访问正常的页面树,而只能访问您的自定义工作流程。

    示例代码

    • 这只是BlogPage 模型的自定义表单的一个基本示例。
    • __init__ 可以扩展以向表单的生成方式添加自定义逻辑(例如,使某些字段只读,甚至“隐藏”某些字段)。
    • save 可以扩展为向只读字段添加服务器端验证,并提供面向用户的错误消息。
    • 可以通过检查 self.instance.pk(主键)是否存在来添加创建“新”页面的逻辑以及编辑现有页面的逻辑。
    # other imports
    from wagtail.admin.forms import WagtailAdminPageForm
    
    
    class BlogPageForm(WagtailAdminPageForm):
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            instance = getattr(self, 'instance', None)
            if not instance.pk:
                # this is a NEW blog entry form - only allow title to be enabled, disable other fields
                self.fields['description'].widget.attrs['readonly'] = True
            if instance.pk:
                # assume title has been entered and saved at this point (required for a new post)
                # disable the title field
                self.fields['title'].widget.attrs['readonly'] = True
    
        def clean(self):
            cleaned_data = super().clean()
            instance = getattr(self, 'instance', None)
    
            title = cleaned_data['title']
            description = cleaned_data['description']
            if not instance.pk:
                # this is a NEW blog entry, check that only the title has been entered
                if not title:
                    self.add_error('title', 'title must be edited before all other fields')
                    return cleaned_data
                if description:
                    self.add_error('description', 'description cannot be entered until title has been completed')
    
            if instance.pk:
                # an existing blog entry, do not allow title to be changed
                print('title', instance.title, title)
                if instance.title != title:
                    self.add_error('title', 'title cannot be edited after the initial save')
    
    
    class BlogPage(Page):
        # ...fields
    
        base_form_class = BlogPageForm
    

    【讨论】:

      【解决方案2】:

      可以通过额外的 custom.css 文件轻松完成

      1. 使用insert_global_admin_css Wagtail 钩子,将路径添加到您的 custom.css 文件。这是文档链接:https://docs.wagtail.io/en/latest/reference/hooks.html#insert-global-admin-css

      2. 然后将类名(例如“myReadonlyInput”)添加到页面模型中的FieldPanel。这将为带有输入字段的 li 元素添加新类。

        FieldPanel("field_name", classname="myReadonlyInput"),

      3. 在 custom.css 文件中添加 pointer-events:none; 到属于 li 元素新类的输入字段:

        li.myReadonlyInput  div.input input {
            background-color: rgb(239 239 239);
            color: rgb(99 99 99);
            pointer-events:none;
            cursor:text;
        }
        

      这样只有在任何字段模型中添加类名,输入字段才会灰显,无法访问。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-05-28
        • 1970-01-01
        • 1970-01-01
        • 2018-11-12
        • 2011-04-20
        • 2017-11-22
        • 1970-01-01
        相关资源
        最近更新 更多