class UserAdminView(ModelView, ActionsMixin): column_searchable_list = ('username', ) column_sortable_list = ('username', 'admin') column_exclude_list = ('password', ) form_excluded_columns = ('password', ) # form_edit_rules = ('username', 'admin',) form_edit_rules = (rules.Header('Edit info for:'), 'username', 'admin', 'notes', rules.Header('Reset Password'), 'new_password', 'confirm') # form_create_rules = ('username', 'admin', 'email', 'notes', 'password') form_create_rules = ( rules.FieldSet(('username', 'notes', 'email'), 'Personal'), rules.FieldSet(('admin', 'password'), 'Permission'), ) def is_accessible(self): return current_user.is_authenticated and current_user.is_admin() def inaccessible_callback(self, name, *kwargs): return redirect(url_for('home', next=request.url)) def scaffold_form(self): form_class = super(UserAdminView, self).scaffold_form() form_class.password = PasswordField('Password') form_class.new_password = PasswordField('New Password') form_class.confirm = PasswordField('Confirm_ New Password') return form_class def create_model(self, form): model = self.model(form.username.data, form.password.data, form.admin.data) form.populate_obj(model) model.password = bcrypt.generate_password_hash(form.password.data) self.session.add(model) self._on_model_change(form, model, True) self.session.commit() form_overrides = dict(notes=CKTextAreaField) create_template = 'edit.html' edit_template = 'edit.html' def update_model(self, form, model): form.populate_obj(model) if form.new_password.data: if form.new_password.data != form.confirm.data: flash('Passwords must match!!!') return model.password = bcrypt.generate_password_hash( form.new_password.data) self.session.add(model) self._on_model_change(form, model, False) self.session.commit()
class UserModelView(ModelView): can_view_details = True can_delete = False column_exclude_list = ('password', ) column_default_sort = 'id' column_filters = ( 'name', 'username', ) create_template = 'user/create.html' edit_template = 'user/edit.html' form_create_rules = [ rules.FieldSet(('username', ), 'Account'), # Header and four fields. Email field will go above phone field. rules.FieldSet(('first_name', 'last_name', 'email', 'phone'), 'Personal'), # Separate header and few fields rules.Header('Location'), rules.Field('city'), # String is resolved to form field, so there's no need to explicitly use `rules.Field` 'country', # Show macro that's included in the templates rules.Container('rule_demo.wrap', rules.Field('notes')) ] form_edit_rules = form_create_rules
class AdministratorView(BaseAdminView): form_edit_rules = ('username', rules.Header('Reset Password'), 'new_password', 'confirm') form_create_rules = ('username', 'email', 'password') def scaffold_form(self): form_class = super(AdministratorView, self).scaffold_form() form_class.password = PasswordField('Password') form_class.new_password = PasswordField('New Password') form_class.confirm = PasswordField('Confirm') return form_class def create_model(self, form): password_hash = generate_password_hash(form.password.data) model = self.model(username=form.username.data, email=form.email.data, password_hash=password_hash) form.populate_obj(model) self.session.add(model) self._on_model_change(form, model, True) self.session.commit() def update_model(self, form, model): form.populate_obj(model) if form.new_password.data: if form.new_password.data != form.confirm.data: flash('Passwords must match', 'warning') return model.password_hash = generate_password_hash( form.new_password.data) self.session.add(model) self._on_model_change(form, model, False) self.session.commit()
class UserAdminView(ModelView, ActionsMixin): column_searchable_list = ('username', ) column_sortable_list = ('username', 'admin') column_exclude_list = ('pwdhash', ) form_excluded_columns = ('pwdhash', ) form_edit_rules = ('username', 'admin', 'roles', 'notes', rules.Header('Reset Password'), 'new_password', 'confirm') form_create_rules = ('username', 'admin', 'roles', 'notes', 'password') form_overrides = dict(notes=CKTextAreaField) create_template = 'edit.html' edit_template = 'edit.html' def is_accessible(self): return current_user.is_authenticated and current_user.is_admin() def scaffold_form(self): form_class = super(UserAdminView, self).scaffold_form() form_class.password = PasswordField('Password') form_class.new_password = PasswordField('New Password') form_class.confirm = PasswordField('Confirm New Password') return form_class def create_model(self, form): if 'C' not in current_user.roles: flash('You are not allowed to create users.', 'warning') return model = self.model(form.username.data, form.password.data, form.admin.data, form.notes.data) form.populate_obj(model) self.session.add(model) self._on_model_change(form, model, True) self.session.commit() def update_model(self, form, model): if 'U' not in current_user.roles: flash('You are not allowed to edit users.', 'warning') return form.populate_obj(model) if form.new_password.data: if form.new_password.data != form.confirm.data: flash('Passwords must match') return model.pwdhash = generate_password_hash(form.new_password.data) self.session.add(model) self._on_model_change(form, model, False) self.session.commit() def delete_model(self, model): if 'D' not in current_user.roles: flash('You are not allowed to delete users.', 'warning') return super(UserAdminView, self).delete_model(model) def is_action_allowed(self, name): if name == 'delete' and 'D' not in current_user.roles: flash('You are not allowed to delete users.', 'warning') return False return True
class UserView(sqla.ModelView): """ This class demonstrates the use of 'rules' for controlling the rendering of forms. """ form_create_rules = [ # Header and four fields. Email field will go above phone field. rules.FieldSet(('name', 'email', 'phone'), u'个人信息'), # Separate header and few fields rules.Header(u'备注'), rules.Field('user_story'), # String is resolved to form field, so there's no need to explicitly use `rules.Field` # 'country', # Show macro from Flask-Admin lib.html (it is included with 'lib' prefix) rules.Container('rule_demo.wrap', rules.Field('notes')) ] # Use same rule set for edit page form_edit_rules = form_create_rules create_template = 'rule_create.html' edit_template = 'rule_edit.html' column_exclude_list = ('password', 'notes') # can_create = False def is_accessible(self): return flask_login.current_user.is_authenticated
def create_form_rules(self): create_form_rules = [ #rules.Header('Personal Info'), #rules.Field('teams'), rules.Header('Project Info'), rules.Field('project_name'), rules.Field('version'), rules.Field('SVN'), rules.Field('notes'), #rules.Field('submitted_at'), rules.Header('Reviewers'), #rules.Field('reviewers'), #rules.Field('reviewer_2'), rules.Field('reviewer1'), rules.Field('reviewer2'), ] return create_form_rules
class UserAdminView(ModelView): column_searchable_list =("username",) column_sortable_list = ("username", "admin") column_exclude_list = ("password",) form_excluded_columns = ("password",) form_edit_rules = ("username", "admin") def is_accessible(self): return current_user.is_authenticated and current_user.is_admin def scaffold_form(self): form_class = super(UserAdminView, self).scaffold_form() form_class.password = PasswordField("Password") form_class.new_password = PasswordField("New Password") form_class.confirm = PasswordField("Confirm New Password") return form_class def create_model(self, form): model = self.model( form.username.data, form.email.data, pbkdf2_sha256.hash(form.password.data), form.description.data, form.admin.data, ) self.session.add(model) self._on_model_change(form, model, True) self.session.commit() form_edit_rules = ("username", "email", "admin", rules.Header("Reset Password"), "new_password", "confirm") form_create_rules = ("username", "email","description", "password", "admin") form_overrides = dict(description=CKTextAreaField) create_template = 'admin/create.html' def update_model(self, form, model): form.populate_obj(model) if form.new_password.data: if form.new_password.data != form.confirm.data: flash("Passwords must match") model.password = pbkdf2_sha256.hash(form.new_password.data) self.session.add(model) self._on_model_change(form, model, False) self.session.commit() def is_accessible(self): return current_user.is_authenticated and current_user.is_admin def inaccessible_callback(self, name, *kwargs): return redirect(url_for("index", next=request.url))
class UserAdminView(ModelView): column_searchable_list = ('username', ) column_sortable_list = ('username', 'admin') column_exclude_list = ('password_hash', ) form_excluded_columns = ('password_hash', ) form_edit_rules = ('username', 'admin') form_edit_rules = ('username', 'admin', rules.Header('Reset Password'), 'new_password', 'confirm') form_create_rules = ('posts', 'username', 'email', 'image_file', 'about_me', 'last_seen', 'password', 'admin') def scaffold_form(self): form_class = super(UserAdminView, self).scaffold_form() form_class.password = PasswordField('Password') form_class.new_password = PasswordField('New Password') form_class.confirm = PasswordField('Confirm') return form_class def create_model(self, form): password_hash = generate_password_hash(form.password.data) model = self.model(username=form.username.data, email=form.email.data, image_file=form.image_file.data, about_me=form.about_me.data, last_seen=form.last_seen.data, password_hash=password_hash, admin=form.admin.data) form.populate_obj(model) self.session.add(model) self._on_model_change(form, model, True) self.session.commit() def update_model(self, form, model): form.populate_obj(model) if form.new_password.data: if form.new_password.data != form.confirm.data: flash('Passwords must match', 'warning') return model.password_hash = generate_password_hash( form.new_password.data) self.session.add(model) self._on_model_change(form, model, False) self.session.commit() def is_accessible(self): return current_user.is_authenticated and current_user.is_admin() def inaccessible_callback(self, name, **kwargs): # redirect to login page if user doesn't have access req = re.findall(r'[0-9]+(.+)', request.url)[0] return redirect(url_for('login', next=req))
class UserAdminView(ModelView): column_searchable_list = ('username', ) column_sortable_list = ('username', ) column_exclude_list = ('password_hash', ) form_excluded_columns = ('password_hash', 'questions') form_edit_rules = ('username', 'role', 'name', 'email', rules.Header('Reset Password'), 'new_password', 'confirm') form_create_rules = ('username', 'role', 'password', 'confirm', 'name', 'email') def scaffold_form(self): form_class = super(UserAdminView, self).scaffold_form() form_class.password = PasswordField('Password') form_class.new_password = PasswordField('New Password') form_class.confirm = PasswordField('Confirm New Password') return form_class def create_model(self, form): model = self.model(username=form.username.data, password=form.password.data, role=form.role.data, name=form.name.data, email=form.email.data) if form.password.data: if form.password.data == form.confirm.data: model.password_hash = generate_password_hash( form.password.data) else: flash('Password must match!') return redirect( url_for('user.create_view', url=url_for('user.index_view'))) self.session.add(model) self._on_model_change(form, model, True) self.session.commit() return redirect(url_for('user.index_view')) def update_model(self, form, model): form.populate_obj(model) if form.new_password.data: if form.new_password.data != form.confirm.data: flash('Password must match!') model.password_hash = generate_password_hash( form.new_password.data) self.session.add(model) self._on_model_change(form, model, False) self.session.commit() return redirect(url_for("user.index_view"))
def test_rule_header(): app, db, admin = setup() Model1, _ = create_models(db) db.create_all() view = CustomModelView(Model1, db.session, form_create_rules=(rules.Header('hello'),)) admin.add_view(view) client = app.test_client() rv = client.get('/admin/model1/new/') eq_(rv.status_code, 200) data = rv.data.decode('utf-8') ok_('<h3>hello</h3>' in data)
class UserView1(sqla.ModelView): def _list_thumbnail(view, context, model, name): if not model.path: return '' return Markup('<img src="%s">' % url_for('static', filename='files/'+form.thumbgen_filename(model.path))) column_formatters = { 'path':_list_thumbnail } # Alternative way to contribute field is to override it completely. # In this case, Flask-Admin won't attempt to merge various parameters for the field. form_extra_fields = { 'path': form.ImageUploadField('Image', base_path=file_path, thumbnail_size=(100, 100, True), url_relative_path='files/') } """ This class demonstrates the use of 'rules' for controlling the rendering of forms. """ form_create_rules = [ # Header and four fields. Email field will go above phone field. rules.FieldSet(('first_name', 'last_name', 'email', 'phone','path'), 'Personal'), # Separate header and few fields rules.Header('Location'), rules.Field('city'), # String is resolved to form field, so there's no need to explicitly use `rules.Field` 'country', # Show macro that's included in the templates rules.Container('rule_demo.wrap', rules.Field('notes')) #rules.FieldSet('path') ] # Use same rule set for edit page form_edit_rules = form_create_rules create_template = 'create_user.html' edit_template = 'edit_user.html'
class UserAdminView(ModelView): column_searchable_list = ('username', 'email') column_sortable_list = ('username', 'admin') column_exclude_list = ('pwdhash', ) form_excluded_columns = ('pwdhash', ) form_edit_rules = ('username', 'admin', rules.Header('Reset Password'), 'new_password', 'confirm') form_create_rules = ('username', 'fullname', 'email', 'admin', 'password') def is_accessible(self): return current_user.is_authenticated and current_user.is_admin() def scaffold_form(self): form_class = super(UserAdminView, self).scaffold_form() form_class.password = PasswordField('Password') form_class.new_password = PasswordField('New Password') form_class.confirm = PasswordField('Confirm New Password') return form_class def create_model(self, form): model = self.model(username=form.username.data, pwdhash=generate_password_hash(form.password.data), admin=form.admin.data, email=form.email.data, fullname=form.fullname.data) form.populate_obj(model) self.session.add(model) self._on_model_change(form, model, True) self.session.commit() flash('Created new user successfully', category='success') def update_model(self, form, model): form.populate_obj(model) if form.new_password.data: if form.new_password.data != form.confirm.data: flash('Passwords must match') return model.pwdhash = generate_password_hash(form.new_password.data) self.session.add(model) self._on_model_change(form, model, False) self.session.commit() flash('Updated password successfully', category='success')
class UserView(sqla.ModelView): """ Esta clase demuestra el uso de 'reglas' para controlar la representación de formularios. """ form_create_rules = [ # Header y los 4 campos.. rules.FieldSet(('first_name', 'last_name', 'email', 'phone'), 'Personal'), # Separando headr y campos rules.Header('Location'), rules.Field('city'), 'country', # Mostrar macro de Flask-Admin lib.html (se incluye con el prefijo 'lib') rules.Container('rule_demo.wrap', rules.Field('notes')) ] # Use same rule set for edit page form_edit_rules = form_create_rules create_template = 'rule_create.html' edit_template = 'rule_edit.html'
class UserView(sqla.ModelView): """ This class demonstrates the use of 'rules' for controlling the rendering of forms. """ form_create_rules = [ # Header and four fields. Email field will go above phone field. rules.FieldSet(('first_name', 'last_name', 'email', 'phone'), 'Personal'), # Separate header and few fields rules.Header('Location'), rules.Field('city'), # String is resolved to form field, so there's no need to explicitly use `rules.Field` 'country', # Show macro from Flask-Admin lib.html (it is included with 'lib' prefix) rules.Container('rule_demo.wrap', rules.Field('notes')) ] # Use same rule set for edit page form_edit_rules = form_create_rules create_template = 'rule_create.html' edit_template = 'rule_edit.html'
class UserAdminView(MyAccessModelView): column_searchable_list = ('username', ) column_sortable_list = ('username', 'admin') column_exclude_list = ('about_me', 'last_seen') form_excluded_columns = ('password_hash', 'last_seen') form_edit_rules = ('username', 'admin') def scaffold_form(self): form_class = super(UserAdminView, self).scaffold_form() form_class.password = PasswordField('Password') form_class.new_password = PasswordField('New Password') form_class.confirm = PasswordField('Confirm New Password') return form_class def create_model(self, form): model = self.model(username=form.username.data, password_hash=bcrypt.generate_password_hash( form.password.data), admin=form.admin.data) form.populate_obj(model) self.session.add(model) self._on_model_change(form, model, True) self.session.commit() form_edit_rules = ('username', 'admin', rules.Header('Reset Password'), 'new_password', 'confirm') form_create_rules = ('username', 'email', 'password', 'image_file', 'about_me', 'admin') def update_model(self, form, model): form.populate_obj(model) if form.new_password.data: if form.new_password.data != form.confirm.data: flash('Passwords must match') return model.password_hash = bcrypt.generate_password_hash( form.new_password.data) self.session.add(model) self._on_model_change(form, model, False) self.session.commit()
class UserAdminView(AdminModelView): column_searchable_list = ('username', ) column_sortable_list = ('username', 'is_admin') column_exclude_list = ('password_hash', ) form_excluded_columns = ('password_hash', ) form_edit_rules = ('username', 'is_admin', rules.Header('Reset Password'), 'new_password', 'confirm') form_create_rules = ('username', 'password', 'is_admin') def scaffold_form(self): form_class = super(UserAdminView, self).scaffold_form() form_class.password = PasswordField('Password') form_class.new_password = PasswordField('New Password') form_class.confirm = PasswordField('Confirm New Password') return form_class def create_model(self, form): model = self.model(username=form.username.data, is_admin=form.is_admin.data) model.set_password(form.password.data) db.session.add(model) self._on_model_change(form, model, True) self.session.commit() return model def update_model(self, form): model = self.model(username=form.username.data, is_admin=form.is_admin.data) if form.new_password.data: if form.new_password.data != form.confirm.data: flash('New password and confirm must match') return False model.set_password(form.new_password.data) self.session.add(model) self._on_model_change(form, model, False) self.session.commit() return True
class UserView(sqla.ModelView): """ This class demonstrates the use of 'rules' for controlling the rendering of forms. """ form_create_rules = [ # Header and four fields. Email field will go above phone field. rules.FieldSet(("first_name", "last_name", "email", "phone"), "Personal"), # Separate header and few fields rules.Header("Location"), rules.Field("city"), # String is resolved to form field, so there's no need to explicitly use `rules.Field` "country", # Show macro from Flask-Admin lib.html (it is included with 'lib' prefix) rules.Container("rule_demo.wrap", rules.Field("notes")), ] # Use same rule set for edit page form_edit_rules = form_create_rules create_template = "rule_create.html" edit_template = "rule_edit.html"
class ToolModelView(ModelView): can_create = False can_edit = False form_rules = [ rules.FieldSet((), u'工具详情'), rules.Field(u'project_title'), rules.Field(u'size'), rules.Field(u'name'), rules.Field(u'description'), rules.Field(u'number'), rules.Header(u'校验'), rules.Field(u'belong'), ] column_editable_list = ('size', ) column_searchable_list = ('project_title', ) column_sortable_list = ('project_title', 'name') column_exclude_list = ('belong', ) column_labels = dict(project_title=u'项目', name=u'名称', size=u'尺寸', number=u'数量', description=u'备注', belong=u'校验') column_descriptions = dict(project_title=u'''工具所用于的拆装项目, 请保证 "Belong"列的内容与项目名一致(例如 "737更换滑行灯工具"对应 "<"Object 737更换滑行灯工具">"), 保证录入工具和拆装项目匹配''', number=u'若不填,系统默认为 1', name=u'工具的名称', size=u'工具的大小或者尺寸')
class ProUserView(SuspensionMixin, BaseAdminView): can_edit = True can_create = True column_list = [ "id", "isActive", "email", "firstName", "lastName", "publicName", "dateOfBirth", "departementCode", "phoneNumber", "postalCode", "isEmailValidated", "validationToken", "actions", ] column_labels = dict( email="Email", isActive="Est activé", firstName="Prénom", lastName="Nom", publicName="Nom d'utilisateur", dateOfBirth="Date de naissance", departementCode="Département", phoneNumber="Numéro de téléphone", postalCode="Code postal", isEmailValidated="Email validé ?", validationToken="Jeton de validation d'adresse email", has_beneficiary_role="Bénéficiaire 18 ans ?", has_underage_beneficiary_role="Bénéficiaire 15-17 ?", ) column_searchable_list = [ "id", "publicName", "email", "firstName", "lastName" ] column_filters = [ "postalCode", "has_beneficiary_role", "has_underage_beneficiary_role", "isEmailValidated" ] form_columns = [ "email", "firstName", "lastName", "dateOfBirth", "departementCode", "postalCode", ] form_create_rules = ( rules.Header("Utilisateur créé :"), "email", "firstName", "lastName", "phoneNumber", "dateOfBirth", "departementCode", "postalCode", rules.Header("Structure créée :"), "offererSiren", "offererName", "offererPostalCode", "offererCity", "csrf_token", ) # This override is necessary to prevent SIREN and offererName to be in edit form as well def get_create_form(self) -> Form: form = super().get_form() form.email = StringField("Email", [DataRequired()], filters=[filter_email]) form.postalCode = StringField("Code postal", [validators.DataRequired()]) form.offererSiren = StringField( "SIREN", [ validators.DataRequired(), validators.Length(9, 9, "Un SIREN contient 9 caractères"), unique_siren ], ) form.offererName = StringField("Nom de la structure", [validators.DataRequired()]) form.offererPostalCode = StringField( "Code postal de la structure", [ validators.DataRequired(), validators.Regexp( POSTAL_CODE_REGEX, message="Le code postal saisi doit être valide"), ], ) form.offererCity = StringField("Ville de la structure", [validators.DataRequired()]) form.firstName = StringField("Prénom", [validators.DataRequired()]) form.lastName = StringField("Nom", [validators.DataRequired()]) form.phoneNumber = StringField("Numéro de tél.", [validators.DataRequired()]) return form def get_edit_form(self) -> Form: form = super().get_form() form.email = StringField("Email", [DataRequired()], filters=[filter_email]) return form def on_model_change(self, form: Form, model: User, is_created: bool) -> None: model.publicName = f"{model.firstName} {model.lastName}" if is_created: model.remove_beneficiary_role() model.add_pro_role() fulfill_account_password(model) offerer = create_offerer(form) create_digital_venue(offerer) user_offerer = create_user_offerer(user=model, offerer=offerer) model.userOfferers = [user_offerer] super().on_model_change(form, model, is_created) def after_model_change(self, form: Form, model: User, is_created: bool) -> None: if is_created: resetPasswordToken = create_reset_password_token( model, token_life_time=RESET_PASSWORD_TOKEN_LIFE_TIME_EXTENDED) reset_password_link = build_pc_pro_create_password_link( resetPasswordToken.value) flash(f"Lien de création de mot de passe : {reset_password_link}") if current_user: send_reset_password_link_to_admin_email( model, current_user.email, reset_password_link) super().after_model_change(form, model, is_created) def get_query(self) -> query: return User.query.join(UserOfferer).distinct(User.id).from_self() def get_count_query(self) -> query: return self.session.query(func.count(distinct( User.id))).select_from(User).join(UserOfferer)
class OrgView(CustomWithInlineFormsModelView): # create_modal = True # edit_modal = True model_form_converter = ModelWithShortTimeFieldConverter column_descriptions = { 'org_id': "Organization's identifier (domain name).", } can_view_details = True # essential to display PK column in the "list" view column_display_pk = True column_searchable_list = ['org_id'] column_list = [ 'org_id', 'actual_name', 'full_access', # 'stream_api_enabled', # 'email_notification_enabled', # 'email_notification_business_days_only', 'access_to_inside', 'access_to_threats', 'access_to_search', ] form_columns = [ 'org_id', 'actual_name', 'org_groups', 'users', 'entity', 'full_access', 'stream_api_enabled', # authorization: 'access_to_inside', 'inside_subsources', 'inside_off_subsources', 'inside_subsource_groups', 'inside_off_subsource_groups', 'access_to_threats', 'threats_subsources', 'threats_off_subsources', 'threats_subsource_groups', 'threats_off_subsource_groups', 'access_to_search', 'search_subsources', 'search_off_subsources', 'search_subsource_groups', 'search_off_subsource_groups', # notification settings: 'email_notification_enabled', 'email_notification_addresses', 'email_notification_times', 'email_notification_language', 'email_notification_business_days_only', # filter-related options: 'inside_filter_asns', 'inside_filter_ccs', 'inside_filter_fqdns', 'inside_filter_ip_networks', 'inside_filter_urls', ] form_rules = [ rules.Header('Organization basic data'), rules.Field('org_id'), rules.Field('actual_name'), rules.Field('full_access'), rules.Field('stream_api_enabled'), rules.Header('Groups and users'), rules.Field('org_groups'), rules.Field('users'), rules.Header('"Inside" access zone'), rules.Field('access_to_inside'), rules.Field('inside_subsources'), rules.Field('inside_off_subsources'), rules.Field('inside_subsource_groups'), rules.Field('inside_off_subsource_groups'), rules.Header('"Threats" access zone'), rules.Field('access_to_threats'), rules.Field('threats_subsources'), rules.Field('threats_off_subsources'), rules.Field('threats_subsource_groups'), rules.Field('threats_off_subsource_groups'), rules.Header('"Search" access zone'), rules.Field('access_to_search'), rules.Field('search_subsources'), rules.Field('search_off_subsources'), rules.Field('search_subsource_groups'), rules.Field('search_off_subsource_groups'), rules.Header('E-mail notification settings'), rules.Field('email_notification_enabled'), rules.Field('email_notification_addresses'), rules.Field('email_notification_times'), rules.Field('email_notification_language'), rules.Field('email_notification_business_days_only'), rules.Header('"Inside" event criteria (checked by n6filter)'), rules.Field('inside_filter_asns'), rules.Field('inside_filter_ccs'), rules.Field('inside_filter_fqdns'), rules.Field('inside_filter_ip_networks'), rules.Field('inside_filter_urls'), rules.Header('Related entity'), rules.Field('entity'), ] inline_models = [ UserInlineFormAdmin(User), EMailNotificationAddress, NotificationTimeInlineFormAdmin(EMailNotificationTime), InsideFilterASN, InsideFilterCC, InsideFilterFQDN, InsideFilterIPNetwork, InsideFilterURL, ]
class UserModelView(ModelView): column_searchable_list = ('username', ) column_sortable_list = ('username', 'admin') column_list = ( 'username', 'email', 'admin', ) column_exclude_list = ('pwdhash', ) form_excluded_columns = ('pwdhash', ) # form_edit_rules = ('username', 'admin') # form_create_rules = ('username', 'password', 'admin') form_edit_rules = ('username', 'email', 'about_me', 'admin', rules.Header('Reset Password'), 'new_password', 'confirm') form_create_rules = ('username', 'email', 'admin', 'password') form_overrides = dict(about_me=CKTextAreaField) create_template = 'edit.html' edit_template = 'edit.html' def scaffold_form(self): form_class = super(UserModelView, self).scaffold_form() form_class.password = PasswordField( 'Password', validators=[ Length( min=8, message='Поле повинно бути довжиною більше 8 символів!'), DataRequired(message="Це поле є обов'язковим!") ]) form_class.new_password = PasswordField('New Password') form_class.confirm = PasswordField('Confirm New Password') return form_class def create_model(self, form): model = self.model( form.username.data, form.email.data, bcrypt.generate_password_hash(form.password.data).decode('utf-8'), form.admin.data) # form.populate_obj(model) self.session.add(model) self._on_model_change(form, model, True) self.session.commit() def update_model(self, form, model): form.populate_obj(model) if form.new_password.data: if form.new_password.data != form.confirm.data: flash('Passwords must match') return model.password = bcrypt.generate_password_hash( form.new_password.data).decode('utf-8') self.session.add(model) self._on_model_change(form, model, False) self.session.commit() def is_accessible(self): return current_user.is_authenticated and current_user.admin def inaccessible_callback(self, name, *kwargs): return redirect(url_for('index', next=request.url))
class IdentifierSettingView(ModelView): """Pidstore Identifier admin view.""" can_create = True can_edit = True can_delete = False can_view_details = True create_template = config.WEKO_PIDSTORE_IDENTIFIER_TEMPLATE_CREATOR edit_template = config.WEKO_PIDSTORE_IDENTIFIER_TEMPLATE_EDITOR column_list = ( 'repository', 'jalc_doi', 'jalc_crossref_doi', 'jalc_datacite_doi', 'cnri', 'suffix', 'jalc_flag', 'jalc_crossref_flag', 'jalc_datacite_flag', 'cnri_flag', ) column_searchable_list = ('repository', 'jalc_doi', 'jalc_crossref_doi', 'jalc_datacite_doi', 'cnri', 'suffix') column_details_list = ('repository', 'jalc_doi', 'jalc_crossref_doi', 'jalc_datacite_doi', 'cnri', 'suffix', 'created_userId', 'created_date', 'updated_userId', 'updated_date') form_extra_fields = { 'repo_selected': StringField('Repository Selector'), } form_create_rules = [ rules.Header(_('Prefix')), 'repository', 'jalc_doi', 'jalc_crossref_doi', 'jalc_datacite_doi', 'cnri', rules.Header(_('Suffix')), 'suffix', rules.Header(_('Enable/Disable')), 'jalc_flag', 'jalc_crossref_flag', 'jalc_datacite_flag', 'cnri_flag', 'repo_selected', ] form_edit_rules = form_create_rules column_labels = dict(repository=_('Repository'), jalc_doi=_('JaLC DOI'), jalc_crossref_doi=_('JaLC CrossRef DOI'), jalc_datacite_doi=_('JaLC DataCite DOI'), cnri=_('CNRI'), suffix=_('Semi-automatic Suffix')) def _validator_halfwidth_input(form, field): """ Valid input character set. :param form: Form used to create/update model :param field: Template fields contain data need validator """ if field.data is None: return else: try: for inchar in field.data: if unicodedata.east_asian_width(inchar) in 'FWA': raise ValidationError( _('Only allow half with 1-bytes character in input' )) except Exception as ex: raise ValidationError('{}'.format(ex)) form_args = { 'jalc_doi': { 'validators': [_validator_halfwidth_input] }, 'jalc_crossref_doi': { 'validators': [_validator_halfwidth_input] }, 'jalc_datacite_doi': { 'validators': [_validator_halfwidth_input] }, 'cnri': { 'validators': [_validator_halfwidth_input] }, 'suffix': { 'validators': [_validator_halfwidth_input] } } form_widget_args = { 'jalc_doi': { 'maxlength': 100, 'readonly': True, }, 'jalc_crossref_doi': { 'maxlength': 100, 'readonly': True, }, 'jalc_datacite_doi': { 'maxlength': 100, 'readonly': True, }, 'cnri': { 'maxlength': 100, 'readonly': True, }, 'suffix': { 'maxlength': 100, } } form_overrides = { 'repository': QuerySelectField, } def on_model_change(self, form, model, is_created): """ Perform some actions before a model is created or updated. Called from create_model and update_model in the same transaction (if it has any meaning for a store backend). By default does nothing. :param form: Form used to create/update model :param model: Model that will be created/updated :param is_created: Will be set to True if model was created and to False if edited """ # Update hidden data automation if is_created: model.created_userId = current_user.get_id() model.created_date = datetime.utcnow().replace(microsecond=0) model.updated_userId = current_user.get_id() model.updated_date = datetime.utcnow().replace(microsecond=0) model.repository = str(model.repository.id) pass def on_form_prefill(self, form, id): form.repo_selected.data = form.repository.data pass def create_form(self, obj=None): """ Instantiate model delete form and return it. Override to implement custom behavior. The delete form originally used a GET request, so delete_form accepts both GET and POST request for backwards compatibility. :param obj: input object """ return self._use_append_repository( super(IdentifierSettingView, self).create_form()) def edit_form(self, obj): """ Instantiate model editing form and return it. Override to implement custom behavior. :param obj: input object """ return self._use_append_repository( super(IdentifierSettingView, self).edit_form(obj)) def _use_append_repository(self, form): form.repository.query_factory = self._get_community_list form.repo_selected.data = 'Root Index' return form def _get_community_list(self): try: query_data = Community.query.all() query_data.insert(0, Community(id='Root Index')) except Exception as ex: current_app.logger.debug(ex) return query_data
class ProductAdminView(StaffModelView): column_list = ( "name", "slug", "brand", "in_stock", "price", "date_updated", "date_created", ) column_hide_backrefs = False column_filters = ( "in_stock", "active", ) column_editable_list = ("in_stock", ) column_searchable_list = ("name", ) column_sortable_list = ( "name", "brand", "price", "date_created", "date_updated", ) form_excluded_columns = ( "date_updated", "date_created", ) form_create_rules = ( rules.Header("General"), "name", "brand", "slug", "tags", "description", "active", "in_stock", "price", ) form_edit_rules = ( rules.Header("General"), "name", "brand", "slug", "tags", "description", "active", "in_stock", "price", ) def on_model_change(self, form, model, is_created): if not model.slug: model.slug = slugify(model.name) if is_created: model.date_created = datetime.utcnow() else: model.date_updated = datetime.utcnow() def after_model_change(self, form, model, is_created): Product.reindex()
class UserAdminView(AdminModelView): column_list = ( "email", "first_name", "last_name", "active", "staff", "admin", ) column_filters = ( "active", "staff", "admin", ) column_searchable_list = ("email", ) column_sortable_list = ("active", ) column_editable_list = ( "active", "staff", "admin", ) form_excluded_columns = ("hashed_password", ) form_edit_rules = ( "first_name", "last_name", "email", "active", "staff", "admin", rules.Header("Reset Password"), "new_password", "confirm", ) form_create_rules = ( "email", "password", "staff", "admin", ) def scaffold_form(self): form_class = super().scaffold_form() form_class.email = EmailField( "Email", [validators.Email(), validators.DataRequired()]) form_class.password = PasswordField("Password", [ validators.DataRequired(), ]) form_class.new_password = PasswordField("New Password") form_class.confirm = PasswordField("Confirm Password") return form_class def create_model(self, form): try: model = self.model( email=form.email.data, staff=form.staff.data, admin=form.admin.data, password=form.password.data, ) self.session.add(model) self._on_model_change(form, model, True) self.session.commit() except Exception as ex: if not self.handle_view_exception(ex): flash( gettext("Failed to create record. %(error)s", error=str(ex))) self.session.rollback() return False else: self.after_model_change(form, model, True) return model def update_model(self, form, model): try: if hasattr(form, "new_password") and form.new_password: if form.new_password.data: if form.new_password.data != form.confirm.data: flash("New password and confirm password must match.") return False model.set_password(form.new_password.data) if hasattr(form, "staff") and form.staff: model.staff = form.staff.data if hasattr(form, "admin") and form.admin: model.admin = form.admin.data if hasattr(form, "active") and form.active: model.active = form.active.data if hasattr(form, "first_name") and form.first_name: model.first_name = form.first_name.data if hasattr(form, "last_name") and form.last_name: model.last_name = form.last_name.data self._on_model_change(form, model, False) self.session.commit() except Exception as ex: if not self.handle_view_exception(ex): flash( gettext("Failed to create record. %(error)s", error=str(ex))) self.session.rollback() return False else: self.after_model_change(form, model, False) return True def after_model_change(self, form, model, is_created): Product.reindex()
class OrgConfigUpdateRequestView(OrgRequestViewMixin, CustomWithInlineFormsModelView): column_searchable_list = ['status', 'ticket_id', 'org_id'] column_list = [ 'id', 'submitted_on', 'modified_on', 'status', 'ticket_id', 'org_id', ] form_extra_fields = { org_request_helpers.ACTIONS_FIELD_NAME: org_request_helpers.ACTIONS_FIELD_FOR_ORG_CONFIG_UPDATE, } form_columns = [ 'id', 'submitted_on', 'modified_on', 'status', 'ticket_id', 'org_id', 'requesting_user_login', 'additional_comment', org_request_helpers.ACTIONS_FIELD_NAME, 'actual_name_upd', 'actual_name', 'email_notification_enabled_upd', 'email_notification_enabled', 'email_notification_language_upd', 'email_notification_language', 'email_notification_addresses_upd', 'email_notification_addresses', 'email_notification_times_upd', 'email_notification_times', 'asns_upd', 'asns', 'fqdns_upd', 'fqdns', 'ip_networks_upd', 'ip_networks', ] form_widget_args = { # Let it be visible but inactive. (State changes # can be made only with the custom buttons which # fill out the target-status-dedicated invisible # input; that input and those buttons are provided # by `org_request_helpers.ACTIONS_FIELD...` # -- see `form_extra_fields` below.) 'status': { 'disabled': True }, 'org_id': { 'readonly': True }, 'requesting_user_login': { 'readonly': True }, 'additional_comment': { 'readonly': True }, } form_rules = [ rules.Header('Org config update request consideration'), rules.Field('status'), rules.Field('ticket_id'), rules.Field('org_id'), rules.Field('requesting_user_login'), rules.Field('additional_comment'), rules.Field(org_request_helpers.ACTIONS_FIELD_NAME), rules.Header('Updates of basic data'), rules.Field('actual_name_upd'), rules.Field('actual_name'), rules.Header('Updates of "Inside" event criteria'), rules.Field('asns_upd'), rules.Field('asns'), rules.Field('fqdns_upd'), rules.Field('fqdns'), rules.Field('ip_networks_upd'), rules.Field('ip_networks'), rules.Header('Updates of e-mail notifications preferences'), rules.Field('email_notification_enabled_upd'), rules.Field('email_notification_enabled'), rules.Field('email_notification_language_upd'), rules.Field('email_notification_language'), rules.Field('email_notification_addresses_upd'), rules.Field('email_notification_addresses'), rules.Field('email_notification_times_upd'), rules.Field('email_notification_times'), ] org_request_handler_kit = org_request_helpers.org_config_update_request_handler_kit inline_models = [ OrgConfigUpdateRequestEMailNotificationAddress, OrgConfigUpdateRequestEMailNotificationTime, OrgConfigUpdateRequestASN, OrgConfigUpdateRequestFQDN, OrgConfigUpdateRequestIPNetwork, ]
def edit_form_rules(self): if not has_app_context() or current_user.has_role('reviewer1'): edit_form_rules = [ rules.Header('Personal Info'), rules.Field('team'), rules.Field('name'), rules.Header('Project Info'), rules.Field('project_name'), rules.Field('version'), rules.Field('SVN'), #rules.Field('submitted_at'), CustomizableField('notes', field_args={'readonly': False}), rules.Header('Reviewers'), CustomizableField('reviewer1', field_args={'readonly': True}), rules.Field('comment1'), CustomizableField('reviewer2', field_args={'readonly': True}), CustomizableField('comment2', field_args={'readonly': True}), CustomizableField('review1', field_args={'readonly': True}), #rules.Field('reviewers'), ] if not has_app_context() or current_user.has_role('reviewer2'): edit_form_rules = [ rules.Header('Personal Info'), rules.Field('team'), rules.Field('name'), rules.Header('Project Info'), rules.Field('project_name'), rules.Field('version'), rules.Field('SVN'), #rules.Field('submitted_at'), CustomizableField('notes', field_args={'readonly': False}), rules.Header('Reviewers'), CustomizableField('reviewer1', field_args={'readonly': False}), CustomizableField('comment1', field_args={'readonly': True}), CustomizableField('reviewer2', field_args={'readonly': False}), rules.Field('comment2'), CustomizableField('review2', field_args={'readonly': True}), #rules.Field('reviewers'), ] if not has_app_context() or current_user.has_role('user'): edit_form_rules = [ rules.Header('Personal Info'), CustomizableField('team', field_args={'readonly': True}), CustomizableField('name', field_args={'readonly': True}), rules.Header('Project Info'), CustomizableField('project_name', field_args={'readonly': False}), #rules.Field('project_name'), CustomizableField('version', field_args={'readonly': False}), #rules.Field('version'), rules.Field('SVN'), #rules.Field('submitted_at'), rules.Field('notes'), rules.Header('Reviewers'), rules.Field('reviewer1'), #CustomizableField('reviewer1', field_args={ # 'readonly': not self.model.approve #}), CustomizableField('comment1', field_args={'readonly': True}), rules.Field('reviewer2'), CustomizableField('comment2', field_args={'readonly': True}), #rules.Field('reviewers'), #CustomizableField('review2', field_args={ # 'readonly': True #}), ] if not has_app_context() or current_user.has_role( 'superuser') or current_user.has_role('administrator'): edit_form_rules = [ rules.Header('Personal Info'), rules.Field('team'), rules.Field('name'), rules.Header('Project Info'), rules.Field('project_name'), rules.Field('version'), rules.Field('SVN'), #rules.Field('submitted_at'), rules.Field('notes'), rules.Header('Reviewers'), CustomizableField('reviewer1', field_args={'readonly': False}), CustomizableField('comment1', field_args={'readonly': False}), rules.Field('review1'), CustomizableField('reviewer2', field_args={'readonly': False}), CustomizableField('comment2', field_args={'readonly': False}), rules.Field('review2'), rules.Field('comment3'), rules.Field('approve'), #rules.Field('reviewers'), ] ''' if not has_app_context() or current_user.has_role('superuser'): edit_form_rules.append('approve') if not has_app_context() or current_user.has_role('reviewer1'): edit_form_rules.append('review1') if not has_app_context() or current_user.has_role('reviewer2'): edit_form_rules.append('review2') ''' return edit_form_rules
class UserView(MyModelView): #id, username, confirmed, email, __password_hash, role_id, location, about_me, member_since, last_seen can_view_details = True # show a modal dialog with records details form_widget_args = {'id': {'readonly': True}} column_list = [ 'id', 'role_id', 'username', 'confirmed', 'email', 'location', 'about_me', 'member_since', 'last_seen' ] column_auto_select_related = True column_searchable_list = [ 'id', 'role_id', 'username', 'confirmed', 'email', 'location', 'about_me', 'member_since', 'last_seen' ] column_editable_list = [ 'username', 'confirmed', 'email', 'location', 'about_me', 'member_since', ] column_default_sort = [('username', False), ('last_seen', False)] # sort on multiple columns # custom filter: each filter in the list is a filter operation (equals, not equals, etc) # filters with the same name will appear as operations under the same filter column_filters = [ 'username', FilterEqual(column=User.username, name='User Name'), #FilterLastNameBrown(column=User.last_name, name='Last Name', # options=(('1', 'Yes'), ('0', 'No'))), 'member_since', 'email', 'confirmed', 'last_seen', 'location', ] # column_formatters = {'phone_number': phone_number_formatter} # setup edit forms so that only posts created by this user can be selected as 'featured' form_create_rules = [ # Header and four fields. Email field will go above phone field. rules.FieldSet(('username', 'email', 'role', 'confirmed', 'member_since', 'last_seen'), 'Personal'), # Separate header and few fields rules.Header('Location'), rules.Field('location'), # String is resolved to form field, so there's no need to explicitly use `rules.Field` # Show macro that's included in the templates rules.Container('rule_demo.wrap', rules.Field('about_me')) ] form_edit_rules = form_create_rules create_template = 'admin/create_user.html' edit_template = 'admin/edit_user.html' def edit_form(self, obj): return self._filtered_roles(super(UserView, self).edit_form(obj)) def _filtered_roles(self, form): form.role.query_factory = lambda: Role.query.filter( Role.permission == form._obj.id).all() return form
class EntityView(CustomWithInlineFormsModelView): model_form_converter = ModelWithShortTimeFieldConverter can_view_details = True # essential to display PK column in the "list" view column_display_pk = True column_searchable_list = [ 'full_name', 'short_name', 'email', 'city', 'sector_label', 'ticket_id', ] column_list = [ 'full_name', 'short_name', 'email', 'city', 'sector_label', 'ticket_id', ] form_columns = [ # official data: 'id', 'full_name', 'short_name', 'verified', 'email', 'address', 'city', 'postal_code', 'public_essential_service', 'sector', 'ticket_id', 'internal_id', 'extra_ids', 'additional_information', 'asns', 'fqdns', 'ip_networks', 'alert_email', 'contact_points', 'dependant_entities', 'org', ] form_rules = [ rules.Header('Basic data'), rules.Field('full_name'), rules.Field('short_name'), rules.Field('verified'), rules.Field('email'), rules.Field('address'), rules.Field('city'), rules.Field('postal_code'), rules.Header('Supplementary data'), rules.Field('public_essential_service'), rules.Field('sector'), rules.Field('ticket_id'), rules.Field('internal_id'), rules.Field('extra_ids'), rules.Field('additional_information'), rules.Header('Own network data'), rules.Field('asns'), rules.Field('fqdns'), rules.Field('ip_networks'), rules.Header('Contact data'), rules.Field('alert_email'), rules.Field('contact_points'), rules.Header('Dependant entities'), rules.Field('dependant_entities'), rules.Header('Related n6 client Org'), rules.Field('org'), ] inline_models = [ EntityExtraId, EntityASN, EntityFQDN, EntityIPNetwork, EntityContactPointInlineFormAdmin(EntityContactPoint, db_session), DependantEntity, ]
class RegistrationRequestView(OrgRequestViewMixin, CustomWithInlineFormsModelView): column_searchable_list = [ 'status', 'ticket_id', 'org_id', 'actual_name', 'email' ] column_list = [ 'id', 'submitted_on', 'modified_on', 'status', 'ticket_id', 'org_id', 'actual_name', 'email', 'email_notification_language', ] column_descriptions = { 'terms_version': 'The version of the legal terms accepted by the client.', 'terms_lang': 'The language variant of the legal terms accepted by the client.', } form_extra_fields = { org_request_helpers.ACTIONS_FIELD_NAME: org_request_helpers.ACTIONS_FIELD_FOR_REGISTRATION, } form_columns = [ 'id', 'submitted_on', 'modified_on', 'status', 'ticket_id', 'org_group', org_request_helpers.ACTIONS_FIELD_NAME, 'org_id', 'actual_name', 'email', 'submitter_title', 'submitter_firstname_and_surname', 'csr', 'email_notification_language', 'email_notification_addresses', 'asns', 'fqdns', 'ip_networks', 'terms_version', 'terms_lang', ] form_widget_args = { # Let it be visible but inactive. (State changes # can be made only with the custom buttons which # fill out the target-status-dedicated invisible # input; that input and those buttons are provided # by `org_request_helpers.ACTIONS_FIELD...` # -- see `form_extra_fields` below.) 'status': { 'disabled': True }, 'terms_version': { 'readonly': True }, 'terms_lang': { 'readonly': True }, } form_rules = [ rules.Header('Registration request consideration'), rules.Field('status'), rules.Field('ticket_id'), rules.Field('org_group'), rules.Field(org_request_helpers.ACTIONS_FIELD_NAME), rules.Header('Basic and access-related data'), rules.Field('org_id'), rules.Field('actual_name'), rules.Field('email'), rules.Field('submitter_title'), rules.Field('submitter_firstname_and_surname'), rules.Field('csr'), rules.Header('"Inside" event criteria'), rules.Field('asns'), rules.Field('fqdns'), rules.Field('ip_networks'), rules.Header('E-mail notifications preferences'), rules.Field('email_notification_language'), rules.Field('email_notification_addresses'), rules.Header('Legal information'), rules.Field('terms_version'), rules.Field('terms_lang'), ] org_request_handler_kit = org_request_helpers.registration_request_handler_kit inline_models = [ RegistrationRequestEMailNotificationAddress, RegistrationRequestASN, RegistrationRequestFQDN, RegistrationRequestIPNetwork, ]
class OrgView(ShowInlineStringPKModelView): # create_modal = True # edit_modal = True model_form_converter = OrgModelConverter column_descriptions = { 'org_id': 'Organization identifier', } can_view_details = True # essential to display PK column in the "list" view column_display_pk = True column_searchable_list = ['org_id'] column_list = [ 'org_id', 'full_access', # 'stream_api_enabled', # 'email_notifications_enabled', # 'email_notifications_business_days_only', 'access_to_inside', 'access_to_threats', 'access_to_search', ] form_columns = [ 'org_id', 'org_groups', 'users', 'full_access', 'access_to_inside', # 'inside_max_days_old', # 'inside_request_parameters', 'inside_subsources', 'inside_ex_subsources', 'inside_subsource_groups', 'inside_ex_subsource_groups', 'access_to_threats', # 'threats_max_days_old', # 'threats_request_parameters', 'threats_subsources', 'threats_ex_subsources', 'threats_subsource_groups', 'threats_ex_subsource_groups', 'access_to_search', # 'search_max_days_old', # 'search_request_parameters', 'search_subsources', 'search_ex_subsources', 'search_subsource_groups', 'search_ex_subsource_groups', # other options/notifications settings # 'stream_api_enabled', # 'email_notifications_enabled', # 'email_notifications_addresses', # 'email_notifications_times', # 'email_notifications_language', # 'email_notifications_business_days_only', 'inside_filter_asns', 'inside_filter_ccs', 'inside_filter_fqdns', 'inside_filter_ip_networks', 'inside_filter_urls', ] form_rules = [ rules.Header('Basic options for organization'), rules.Field('org_id'), rules.Field('org_groups'), rules.Field('full_access'), rules.Header('Users'), rules.Field('users'), rules.Header('"Inside" resource'), rules.Field('access_to_inside'), # rules.Field('inside_max_days_old'), # rules.Field('inside_request_parameters'), rules.Field('inside_subsources'), rules.Field('inside_ex_subsources'), rules.Field('inside_subsource_groups'), rules.Field('inside_ex_subsource_groups'), rules.Header('"Threats" resource'), rules.Field('access_to_threats'), # rules.Field('threats_max_days_old'), # rules.Field('threats_request_parameters'), rules.Field('threats_subsources'), rules.Field('threats_ex_subsources'), rules.Field('threats_subsource_groups'), rules.Field('threats_ex_subsource_groups'), rules.Header('"Search" resource'), rules.Field('access_to_search'), # rules.Field('search_max_days_old'), # rules.Field('search_request_parameters'), rules.Field('search_subsources'), rules.Field('search_ex_subsources'), rules.Field('search_subsource_groups'), rules.Field('search_ex_subsource_groups'), # rules.Header('Other options'), # rules.Field('stream_api_enabled'), # rules.Field('email_notifications_enabled'), # rules.Field('email_notifications_addresses'), # rules.Field('email_notifications_times'), # rules.Field('email_notifications_language'), # rules.Field('email_notifications_business_days_only'), rules.Header('Criteria for "Inside" (n6filter)'), rules.Field('inside_filter_asns'), rules.Field('inside_filter_ccs'), rules.Field('inside_filter_fqdns'), rules.Field('inside_filter_ip_networks'), rules.Field('inside_filter_urls'), ] inline_models = [ UserInlineFormAdmin(User), EMailNotificationAddress, NotificationTimeInlineFormAdmin(EMailNotificationTime), InsideFilterASN, InsideFilterCC, InsideFilterFQDN, InsideFilterIPNetwork, InsideFilterURL, ]