瀏覽代碼

Validate column length (#3556)

* [fix] validate column length while creating doctype or custom field

* [fix] not allow user to add custom fields in [Custom Field, Customize Form Field, Customize Form, Custom Script, Property Setter]

* [fix] check if fieldname is conflicting with method names

* [fix] don't allow Custom Script and Property Setter to be updated via customize form
version-14
Saurabh 8 年之前
committed by Makarand Bauskar
父節點
當前提交
19ee84a58e
共有 5 個檔案被更改,包括 30 行新增7 行删除
  1. +17
    -5
      frappe/core/doctype/doctype/doctype.py
  2. +1
    -1
      frappe/custom/doctype/custom_field/custom_field.js
  3. +4
    -0
      frappe/custom/doctype/custom_field/custom_field.py
  4. +1
    -1
      frappe/custom/doctype/customize_form/customize_form.js
  5. +7
    -0
      frappe/model/db_schema.py

+ 17
- 5
frappe/core/doctype/doctype/doctype.py 查看文件

@@ -14,7 +14,7 @@ from frappe.model.document import Document
from frappe.custom.doctype.property_setter.property_setter import make_property_setter from frappe.custom.doctype.property_setter.property_setter import make_property_setter
from frappe.desk.notifications import delete_notification_count_for from frappe.desk.notifications import delete_notification_count_for
from frappe.modules import make_boilerplate from frappe.modules import make_boilerplate
from frappe.model.db_schema import validate_column_name
from frappe.model.db_schema import validate_column_name, validate_column_length
import frappe.website.render import frappe.website.render


class InvalidFieldNameError(frappe.ValidationError): pass class InvalidFieldNameError(frappe.ValidationError): pass
@@ -385,9 +385,10 @@ def validate_fields(meta):


1. There are no illegal characters in fieldnames 1. There are no illegal characters in fieldnames
2. If fieldnames are unique. 2. If fieldnames are unique.
3. Fields that do have database columns are not mandatory.
4. `Link` and `Table` options are valid.
5. **Hidden** and **Mandatory** are not set simultaneously.
3. Validate column length.
4. Fields that do have database columns are not mandatory.
5. `Link` and `Table` options are valid.
6. **Hidden** and **Mandatory** are not set simultaneously.
7. `Check` type field has default as 0 or 1. 7. `Check` type field has default as 0 or 1.
8. `Dynamic Links` are correctly defined. 8. `Dynamic Links` are correctly defined.
9. Precision is set in numeric fields and is between 1 & 6. 9. Precision is set in numeric fields and is between 1 & 6.
@@ -406,6 +407,9 @@ def validate_fields(meta):
if len(duplicates) > 1: if len(duplicates) > 1:
frappe.throw(_("Fieldname {0} appears multiple times in rows {1}").format(fieldname, ", ".join(duplicates))) frappe.throw(_("Fieldname {0} appears multiple times in rows {1}").format(fieldname, ", ".join(duplicates)))


def check_fieldname_length(fieldname):
validate_column_length(fieldname)

def check_illegal_mandatory(d): def check_illegal_mandatory(d):
if (d.fieldtype in no_value_fields) and d.fieldtype!="Table" and d.reqd: if (d.fieldtype in no_value_fields) and d.fieldtype!="Table" and d.reqd:
frappe.throw(_("Field {0} of type {1} cannot be mandatory").format(d.label, d.fieldtype)) frappe.throw(_("Field {0} of type {1} cannot be mandatory").format(d.label, d.fieldtype))
@@ -581,7 +585,6 @@ def validate_fields(meta):
frappe.throw(_("Sort field {0} must be a valid fieldname").format(fieldname), frappe.throw(_("Sort field {0} must be a valid fieldname").format(fieldname),
InvalidFieldNameError) InvalidFieldNameError)



fields = meta.get("fields") fields = meta.get("fields")
fieldname_list = [d.fieldname for d in fields] fieldname_list = [d.fieldname for d in fields]


@@ -598,6 +601,7 @@ def validate_fields(meta):
d.fieldname = d.fieldname.lower() d.fieldname = d.fieldname.lower()
check_illegal_characters(d.fieldname) check_illegal_characters(d.fieldname)
check_unique_fieldname(d.fieldname) check_unique_fieldname(d.fieldname)
check_fieldname_length(d.fieldname)
check_illegal_mandatory(d) check_illegal_mandatory(d)
check_link_table_options(d) check_link_table_options(d)
check_dynamic_link_options(d) check_dynamic_link_options(d)
@@ -766,3 +770,11 @@ def init_list(doctype):
doc = frappe.get_meta(doctype) doc = frappe.get_meta(doctype)
make_boilerplate("controller_list.js", doc) make_boilerplate("controller_list.js", doc)
make_boilerplate("controller_list.html", doc) make_boilerplate("controller_list.html", doc)

def check_if_fieldname_conflicts_with_methods(doctype, fieldname):
doc = frappe.get_doc({"doctype": doctype})
method_list = [method for method in dir(doc) if callable(getattr(doc, method))]

if fieldname in method_list:
frappe.throw(_("Fieldname {0} conflicting with meta object").format(fieldname))


+ 1
- 1
frappe/custom/doctype/custom_field/custom_field.js 查看文件

@@ -11,7 +11,7 @@ frappe.ui.form.on('Custom Field', {
['DocType', 'issingle', '=', 0], ['DocType', 'issingle', '=', 0],
]; ];
if(frappe.session.user!=="Administrator") { if(frappe.session.user!=="Administrator") {
filters.push(['DocType', 'module', '!=', 'Core'])
filters.push(['DocType', 'module', 'not in', ['Core', 'Custom']])
} }
return { return {
"filters": filters "filters": filters


+ 4
- 0
frappe/custom/doctype/custom_field/custom_field.py 查看文件

@@ -39,6 +39,10 @@ class CustomField(Document):
if not self.fieldname: if not self.fieldname:
frappe.throw(_("Fieldname not set for Custom Field")) frappe.throw(_("Fieldname not set for Custom Field"))


if not self.flags.ignore_validate:
from frappe.core.doctype.doctype.doctype import check_if_fieldname_conflicts_with_methods
check_if_fieldname_conflicts_with_methods(self.dt, self.fieldname)

def on_update(self): def on_update(self):
frappe.clear_cache(doctype=self.dt) frappe.clear_cache(doctype=self.dt)
if not self.flags.ignore_validate: if not self.flags.ignore_validate:


+ 1
- 1
frappe/custom/doctype/customize_form/customize_form.js 查看文件

@@ -15,7 +15,7 @@ frappe.ui.form.on("Customize Form", {
['DocType', 'custom', '=', 0], ['DocType', 'custom', '=', 0],
['DocType', 'name', 'not in', 'DocType, DocField, DocPerm, User, Role, Has Role, \ ['DocType', 'name', 'not in', 'DocType, DocField, DocPerm, User, Role, Has Role, \
Page, Has Role, Module Def, Print Format, Report, Customize Form, \ Page, Has Role, Module Def, Print Format, Report, Customize Form, \
Customize Form Field'],
Customize Form Field, Property Setter, Custom Field, Custom Script'],
['DocType', 'restrict_to_domain', 'in', frappe.boot.active_domains] ['DocType', 'restrict_to_domain', 'in', frappe.boot.active_domains]
] ]
}; };


+ 7
- 0
frappe/model/db_schema.py 查看文件

@@ -563,6 +563,13 @@ def validate_column_name(n):
frappe.throw(_("Fieldname {0} cannot have special characters like {1}").format(cstr(n), special_characters), InvalidColumnName) frappe.throw(_("Fieldname {0} cannot have special characters like {1}").format(cstr(n), special_characters), InvalidColumnName)
return n return n


def validate_column_length(fieldname):
""" In MySQL maximum column length is 64 characters,
ref: https://dev.mysql.com/doc/refman/5.5/en/identifiers.html"""

if len(fieldname) > 64:
frappe.throw(_("Fieldname is limited to 64 characters ({0})").format(fieldname))

def remove_all_foreign_keys(): def remove_all_foreign_keys():
frappe.db.sql("set foreign_key_checks = 0") frappe.db.sql("set foreign_key_checks = 0")
frappe.db.commit() frappe.db.commit()


Loading…
取消
儲存