docs: def make_form_field(field, model=None, field_cls=None,
                      use_default_value=True,
                      builds_args_map=None):
      """
      make form field according field value
      :param field: such as: str, Form Field instance, dict
          if field is str type, it'll fetch property from model or str is like 'model.name'
          it'll fetch property `name` from `model`
      :param model: if field is str type, it'll may use model value to fetch property
      :param field_cls: if not applied, it'll fetch from property, field_cls sould be Field class
      :param builds_args_map:
      :return: Field instance
      """
      import uliweb.form as form
      from uliweb.form.validators import TEST_MAXLENGTH
  
      builds_args_map = builds_args_map or {}
  
      if model:
          model = get_model(model)
  
      if isinstance(field, BaseField):
          return field
      if isinstance(field, dict) and 'field' in field and isinstance(field['field'], BaseField):
          return field['field']
  
      field_type = None
      prop = None #model property if existed
  
      #process prop
      if isinstance(field, (str, unicode)):
          field = {'name':field}
  
      if isinstance(field, dict):
          prop = field.get('prop')
          if not prop and model:
              #if there is field_name, then use it property class
              field_name = field.get('field_name') or field['name']
              prop = get_model_property(model, field_name)
              #if existed field_cls, then it'll use it to create form field
              if not prop and not field_cls:
                  raise UliwebError("Can't find property %s in Model(%r)" %
                                    (field_name, model.__name__))
      else:
          raise UliwebError("Can't support this field %r type in make_form_field" % type(field))
  
      default_kwargs = {}
      if prop:
          default_kwargs = {
              'label':prop.label or prop.property_name,
              'help_string':prop.hint,
              'placeholder':prop.placeholder,
              'html_attrs':prop.extra.get('html_attrs', {}),
              'required':prop.required,
          }
      kwargs = {
          'label':field.get('label') or field.get('verbose_name') or default_kwargs.get('label'),
          'help_string':field.get('hint') or field.get('help_string') or default_kwargs.get('help_string'),
          'placeholder':field.get('placeholder') or default_kwargs.get('placeholder'),
          'html_attrs':field.get('extra', {}).get('html_attrs', {}) or default_kwargs.get('html_attrs'),
          'required':field.get('required', False) if 'required' in field else default_kwargs.get('required', False)
      }
  
      #add data-url support
      if 'data-url' in field:
          kwargs['html_attrs']['data-url'] = field['data-url']
  
      if use_default_value:
          v = prop.default_value()
          kwargs['default'] = v
  
      if field.get('static'):
          field_type = form.StringField
          kwargs['required'] = False
          kwargs['static'] = True
          if prop.choices is not None:
              kwargs['choices'] = prop.get_choices()
  
      if field.get('hidden'):
          field_type = form.HiddenField
          
      if field_cls:
          field_type = field_cls
      elif not field_type:
          cls = prop.__class__
          type_name = prop.type_name
          if type_name == 'BLOG':
              pass
          elif type_name in ('TEXT', 'JSON'):
              field_type = form.TextField
          elif type_name in ('CHAR', 'VARCHAR', 'UUID'):
              if prop.choices is not None:
                  field_type = form.SelectField
                  kwargs['choices'] = prop.get_choices()
              else:
                  if cls.__name__ == 'FileProperty':
                      field_type = form.FileField
                      kwargs['upload_to'] = prop.upload_to
                      kwargs['upload_to_sub'] = prop.upload_to_sub
                  else:
                      field_type = form.UnicodeField
          elif type_name == 'BOOL':
              field_type = form.BooleanField
          elif type_name == 'DATE':
  #            if not prop.auto_now and not prop.auto_now_add:
              field_type = form.DateField
          elif type_name == 'TIME':
  #            if not prop.auto_now and not prop.auto_now_add:
              field_type = form.TimeField
          elif type_name == 'DATETIME':
  #            if not prop.auto_now and not prop.auto_now_add:
              field_type = form.DateTimeField
          elif type_name == 'DECIMAL':
              field_type = form.StringField
              if prop.choices is not None:
                  field_type = form.SelectField
                  kwargs['choices'] = prop.get_choices()
          elif type_name == 'FLOAT':
              field_type = form.FloatField
          elif type_name == 'INTEGER':
              if prop.choices is not None:
                  field_type = form.SelectField
                  kwargs['choices'] = prop.get_choices()
                  kwargs['datetype'] = int
              else:
                  field_type = form.IntField
          elif type_name == 'ManyToMany':
              kwargs['model'] = prop.reference_class
              field_type = ManyToManySelectField
          elif type_name in ('Reference', 'OneToOne'):
              #field_type = form.IntField
              kwargs['model'] = prop.reference_class
              kwargs['value_field'] = prop.reference_fieldname
              field_type = ReferenceSelectField
          else:
              raise ValueError("Can't support the Property [%s=%s]" %
                               (field['name'], prop.__class__.__name__))
         
      if field_type:
          build_args = builds_args_map.get(field_type, {})
          #add settings.ini configure support
          #so you could add options in settings.ini like this
          #  [GENERIC_FIELDS_MAPPING]
          #  FormFieldClassName = {'build':'model.NewFormFieldTypeClassName', **other args}
          #  
          #  e.g.
          #  [GENERIC_FIELDS_MAPPING]
          #  DateField = {'build':'jquery.widgets.DatePicker'}
          if not build_args:
              build_args = get_fileds_builds().get(field_type, {})
          kwargs.update(build_args)
          
          #add max_length validator
          if issubclass(prop.__class__, (orm.StringProperty, orm.CharProperty, orm.UnicodeProperty)):
              v = kwargs.setdefault('validators', [])
              if isinstance(prop.max_length, int):
                  v.append(TEST_MAXLENGTH(prop.max_length))
  
          f = field_type(**kwargs)
      
          return f