flask-admin:如何根据其他列的值使列只读?

Sam*_*oth 5 python flask flask-sqlalchemy flask-admin

我已经构建了一个允许用户申请代码审查并等待经理批准的系统.

现在我想要实现的目标如下:

  1. 如果它被批准, 在此输入图像描述 然后所有字段都变为只读(我手动将项目名称设置为只读):

在此输入图像描述

  1. 如果被拒绝,

    在此输入图像描述

    然后所有字段都可以编辑.当然,在创建新项目时,所有字段都应该是可编辑的.
    在此输入图像描述

    类的代码ProjectProjectView是如下:

     from flask_sqlalchemy import SQLAlchemy
     from flask_admin.contrib import sqla
     from flask_security import current_user
    
     # Create Flask application
     app = Flask(__name__)
     app.config.from_pyfile('config.py')
     db = SQLAlchemy(app)
    
     class Project(db.Model):
    
            id = db.Column(db.Integer, primary_key=True)
            project_name = db.Column(db.Unicode(128))
            version = db.Column(db.Unicode(128))
            SVN = db.Column(db.UnicodeText)
            approve = db.Column(db.Boolean())
    
            def __unicode__(self):
                return self.name
    
     class ProjectView(sqla.ModelView):
         def is_accessible(self):
             if not current_user.is_active or not current_user.is_authenticated:
                 return False
             return False
    
         @property
         def _form_edit_rules(self):
             return rules.RuleSet(self, self.form_rules)
    
         @_form_edit_rules.setter
         def _form_edit_rules(self, value):
             pass
    
         @property
         def _form_create_rules(self):
             return rules.RuleSet(self, self.form_rules)
    
         @_form_create_rules.setter
         def _form_create_rules(self, value):
             pass
    
         @property
         def form_rules(self):
         form_rules = [
             rules.Field('project_name'),
             rules.Field('version'),
             rules.Field('SVN'),
         ]
         if not has_app_context() or current_user.has_role('superuser'):
             form_rules.append('approve')
    
    Run Code Online (Sandbox Code Playgroud)

    在我看来,由于approve是一个布尔变量,因此应该有条件判断来判断它是0还是1,然后该字段变为只读或相应的可编辑.

    感谢您提前提出建议.

Ser*_*bin 5

正如您已经注意到的那样readonly,为字段设置属性相当简单,但使其动态化有点棘手。

首先,您需要一个自定义字段类:

from wtforms.fields import StringField

class ReadOnlyStringField(StringField):
    @staticmethod
    def readonly_condition():
        # Dummy readonly condition
        return False

    def __call__(self, *args, **kwargs):
        # Adding `readonly` property to `input` field
        if self.readonly_condition():
            kwargs.setdefault('readonly', True)
        return super(ReadOnlyStringField, self).__call__(*args, **kwargs)

    def populate_obj(self, obj, name):
        # Preventing application from updating field value
        # (user can modify web page and update the field)
        if not self.readonly_condition():
            super(ReadOnlyStringField, self).populate_obj(obj, name)
Run Code Online (Sandbox Code Playgroud)

为您的视图设置form_overrides属性:

class ProjectView(sqla.ModelView):
    form_overrides = {
        'project_name': ReadOnlyStringField
    }
Run Code Online (Sandbox Code Playgroud)

您需要将自定义readonly_condition函数传递给ReadOnlyStringField实例。我发现的最简单的方法是覆盖edit_form方法:

class ProjectView(sqla.ModelView):
    def edit_form(self, obj=None):
        def readonly_condition():
            if obj is None:
                return False
            return obj.approve
        form = super(ProjectView, self).edit_form(obj)
        form.project_name.readonly_condition = readonly_condition
        return form
Run Code Online (Sandbox Code Playgroud)

快乐编码!


归档时间:

查看次数:

1977 次

最近记录:

7 年,2 月 前