def __init__(self, required=True, widget=None, label=None, initial=None, help_text=None, error_messages=None, show_hidden_initial=False, validators=[], localize=False): # required -- Boolean that specifies whether the field is required. # True by default. # widget -- A Widget class, or instance of a Widget class, that should # be used for this Field when displaying it. Each Field has a # default Widget that it'll use if you don't specify this. In # most cases, the default widget is TextInput. # label -- A verbose name for this field, for use in displaying this # field in a form. By default, Django will use a "pretty" # version of the form field name, if the Field is part of a # Form. # initial -- A value to use in this Field's initial display. This value # is *not* used as a fallback if data isn't given. # help_text -- An optional string to use as "help text" for this Field. # error_messages -- An optional dictionary to override the default # messages that the field will raise. # show_hidden_initial -- Boolean that specifies if it is needed to render a # hidden widget with initial value after widget. # validators -- List of addtional validators to use # localize -- Boolean that specifies if the field should be localized. if label is not None: label = smart_text(label) self.required, self.label, self.initial = required, label, initial self.show_hidden_initial = show_hidden_initial if help_text is None: self.help_text = '' else: self.help_text = smart_text(help_text) widget = widget or self.widget if isinstance(widget, type): widget = widget() # Trigger the localization machinery if needed. self.localize = localize if self.localize: widget.is_localized = True # Let the widget know whether it should display as required. widget.is_required = self.required # Hook into self.widget_attrs() for any Field-specific HTML attributes. extra_attrs = self.widget_attrs(widget) if extra_attrs: widget.attrs.update(extra_attrs) self.widget = widget # Increase the creation counter, and save our local copy. self.creation_counter = Field.creation_counter Field.creation_counter += 1 messages = {} for c in reversed(self.__class__.__mro__): messages.update(getattr(c, 'default_error_messages', {})) messages.update(error_messages or {}) self.error_messages = messages self.validators = self.default_validators + validators
def test_smart_text(self): class Test: if six.PY3: def __str__(self): return 'ŠĐĆŽćžšđ' else: def __str__(self): return 'ŠĐĆŽćžšđ'.encode('utf-8') class TestU: if six.PY3: def __str__(self): return 'ŠĐĆŽćžšđ' def __bytes__(self): return b'Foo' else: def __str__(self): return b'Foo' def __unicode__(self): return '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111' self.assertEqual(smart_text(Test()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111') self.assertEqual(smart_text(TestU()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111') self.assertEqual(smart_text(1), '1') self.assertEqual(smart_text('foo'), 'foo')
def Deserializer(object_list, **options): """ Deserialize simple Python objects back into Django ORM instances. It's expected that you pass the Python objects themselves (instead of a stream or a string) to the constructor """ db = options.pop('using', DEFAULT_DB_ALIAS) models.get_apps() for d in object_list: # Look up the model and starting build a dict of data for it. Model = _get_model(d["model"]) data = {Model._meta.pk.attname : Model._meta.pk.to_python(d["pk"])} m2m_data = {} # Handle each field for (field_name, field_value) in six.iteritems(d["fields"]): if isinstance(field_value, str): field_value = smart_text(field_value, options.get("encoding", settings.DEFAULT_CHARSET), strings_only=True) field = Model._meta.get_field(field_name) # Handle M2M relations if field.rel and isinstance(field.rel, models.ManyToManyRel): if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): def m2m_convert(value): if hasattr(value, '__iter__') and not isinstance(value, six.text_type): return field.rel.to._default_manager.db_manager(db).get_by_natural_key(*value).pk else: return smart_text(field.rel.to._meta.pk.to_python(value)) else: m2m_convert = lambda v: smart_text(field.rel.to._meta.pk.to_python(v)) m2m_data[field.name] = [m2m_convert(pk) for pk in field_value] # Handle FK fields elif field.rel and isinstance(field.rel, models.ManyToOneRel): if field_value is not None: if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): if hasattr(field_value, '__iter__') and not isinstance(field_value, six.text_type): obj = field.rel.to._default_manager.db_manager(db).get_by_natural_key(*field_value) value = getattr(obj, field.rel.field_name) # If this is a natural foreign key to an object that # has a FK/O2O as the foreign key, use the FK value if field.rel.to._meta.pk.rel: value = value.pk else: value = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value) data[field.attname] = value else: data[field.attname] = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value) else: data[field.attname] = None # Handle all other fields else: data[field.name] = field.to_python(field_value) yield base.DeserializedObject(Model(**data), m2m_data)
def vat_number_check_digit(vat_number): "Calculate Italian VAT number check digit." normalized_vat_number = smart_text(vat_number).zfill(10) total = 0 for i in range(0, 10, 2): total += int(normalized_vat_number[i]) for i in range(1, 11, 2): quotient , remainder = divmod(int(normalized_vat_number[i]) * 2, 10) total += quotient + remainder return smart_text((10 - total % 10) % 10)
def _auto_id(self): """ Calculates and returns the ID attribute for this BoundField, if the associated Form has specified auto_id. Returns an empty string otherwise. """ auto_id = self.form.auto_id if auto_id and '%s' in smart_text(auto_id): return smart_text(auto_id) % self.html_name elif auto_id: return self.html_name return ''
def clean(self, value): super(IDPhoneNumberField, self).clean(value) if value in EMPTY_VALUES: return "" phone_number = re.sub(r"[\-\s\(\)]", "", smart_text(value)) if phone_re.search(phone_number): return smart_text(value) raise ValidationError(self.error_messages["invalid"])
def clean(self, value): value = super(BRStateChoiceField, self).clean(value) if value in EMPTY_VALUES: value = '' value = smart_text(value) if value == '': return value valid_values = set([smart_text(k) for k, v in self.widget.choices]) if value not in valid_values: raise ValidationError(self.error_messages['invalid']) return value
def valid_value(self, value): "Check to see if the provided value is a valid choice" for k, v in self.choices: if isinstance(v, (list, tuple)): # This is an optgroup, so look inside the group for options for k2, v2 in v: if value == smart_text(k2): return True else: if value == smart_text(k): return True return False
def handle_label(self, path, **options): verbosity = int(options.get('verbosity', 1)) result = finders.find(path, all=options['all']) path = smart_text(path) if result: if not isinstance(result, (list, tuple)): result = [result] output = '\n '.join( (smart_text(os.path.realpath(path)) for path in result)) self.stdout.write("Found '%s' here:\n %s" % (path, output)) else: if verbosity >= 1: self.stderr.write("No matching file found for '%s'." % path)
def clear_dir(self, path): """ Deletes the given relative path using the destinatin storage backend. """ dirs, files = self.storage.listdir(path) for f in files: fpath = os.path.join(path, f) if self.dry_run: self.log("Pretending to delete '%s'" % smart_text(fpath), level=1) else: self.log("Deleting '%s'" % smart_text(fpath), level=1) self.storage.delete(fpath) for d in dirs: self.clear_dir(os.path.join(path, d))
def urls(self): "Returns a list of (value, URL) tuples." # First, check the urls() method for each plugin. plugin_urls = [] for plugin_name, plugin in self.model.model_databrowse().plugins.items(): urls = plugin.urls(plugin_name, self) if urls is not None: return zip(self.values(), urls) if self.field.rel: m = EasyModel(self.model.site, self.field.rel.to) if self.field.rel.to in self.model.model_list: lst = [] for value in self.values(): if value is None: continue url = '%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, iri_to_uri(value._get_pk_val())) lst.append((smart_text(value), url)) else: lst = [(value, None) for value in self.values()] elif self.field.choices: lst = [] for value in self.values(): url = '%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, iri_to_uri(self.raw_value)) lst.append((value, url)) elif isinstance(self.field, models.URLField): val = list(self.values())[0] lst = [(val, iri_to_uri(val))] else: lst = [(list(self.values())[0], None)] return lst
def _canonify(self, rut): """ Turns the RUT into one normalized format. Returns a (rut, verifier) tuple. """ rut = smart_text(rut).replace(' ', '').replace('.', '').replace('-', '') return rut[:-1], rut[-1].upper()
def _get_file(self, filepath): out = six.StringIO() call_command('findstatic', filepath, all=False, verbosity=0, stdout=out) out.seek(0) lines = [l.strip() for l in out.readlines()] with codecs.open(smart_text(lines[1].strip()), "r", "utf-8") as f: return f.read()
def contents(self): from djangocg.contrib.admin.templatetags.admin_list import _boolean_icon from djangocg.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE field, obj, model_admin = self.field['field'], self.form.instance, self.model_admin try: f, attr, value = lookup_field(field, obj, model_admin) except (AttributeError, ValueError, ObjectDoesNotExist): result_repr = EMPTY_CHANGELIST_VALUE else: if f is None: boolean = getattr(attr, "boolean", False) if boolean: result_repr = _boolean_icon(value) else: result_repr = smart_text(value) if getattr(attr, "allow_tags", False): result_repr = mark_safe(result_repr) else: if value is None: result_repr = EMPTY_CHANGELIST_VALUE elif isinstance(f.rel, ManyToManyRel): result_repr = ", ".join(map(six.text_type, value.all())) else: result_repr = display_for_field(value, f) return conditional_escape(result_repr)
def clean(self, value): super(HRPhoneNumberField, self).clean(value) if value in EMPTY_VALUES: return '' value = re.sub(r'[\-\s\(\)]', '', smart_text(value)) matches = phone_re.search(value) if matches is None: raise ValidationError(self.error_messages['invalid']) # Make sure the prefix is in the list of known codes. prefix = matches.group('prefix') number = matches.group('number') if prefix[0] == '1': number = prefix[1] + number prefix = prefix[0] if prefix not in [choice[0] for choice in HR_PHONE_NUMBER_PREFIX_CHOICES]: raise ValidationError(self.error_messages['area']) # Make sure the number is of adequate length. if prefix=='1' and len(number)!=7: raise ValidationError(self.error_messages['number']) return '%s%s%s' % ('+385',prefix,number)
def label_from_instance(self, obj): """ This method is used to convert objects into strings; it's used to generate the labels for the choices presented by this object. Subclasses can override this method to customize the display of the choices. """ return smart_text(obj)
def handle_m2m_field(self, obj, field): if field.rel.through._meta.auto_created: if self.use_natural_keys and hasattr(field.rel.to, 'natural_key'): m2m_value = lambda value: value.natural_key() else: m2m_value = lambda value: smart_text(value._get_pk_val(), strings_only=True) self._current[field.name] = [m2m_value(related) for related in getattr(obj, field.name).iterator()]
def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH): """Returns choices with a default blank choices included, for use as SelectField choices for this field.""" first_choice = include_blank and blank_choice or [] if self.choices: return first_choice + list(self.choices) rel_model = self.rel.to if hasattr(self.rel, 'get_related_field'): lst = [(getattr(x, self.rel.get_related_field().attname), smart_text(x)) for x in rel_model._default_manager.complex_filter( self.rel.limit_choices_to)] else: lst = [(x._get_pk_val(), smart_text(x)) for x in rel_model._default_manager.complex_filter( self.rel.limit_choices_to)] return first_choice + lst
def clean(self, value): super(USPhoneNumberField, self).clean(value) if value in EMPTY_VALUES: return '' value = re.sub('(\(|\)|\s+)', '', smart_text(value)) m = phone_digits_re.search(value) if m: return '%s-%s-%s' % (m.group(1), m.group(2), m.group(3)) raise ValidationError(self.error_messages['invalid'])
def clean(self, value): super(FRPhoneNumberField, self).clean(value) if value in EMPTY_VALUES: return '' value = re.sub('(\.|\s)', '', smart_text(value)) m = phone_digits_re.search(value) if m: return '%s %s %s %s %s' % (value[0:2], value[2:4], value[4:6], value[6:8], value[8:10]) raise ValidationError(self.error_messages['invalid'])
def clean(self, value): super(PTPhoneNumberField, self).clean(value) if value in EMPTY_VALUES: return '' value = re.sub('(\.|\s)', '', smart_text(value)) m = phone_digits_re.search(value) if m: return '%s' % value raise ValidationError(self.error_messages['invalid'])
def clean(self, value): super(INPhoneNumberField, self).clean(value) if value in EMPTY_VALUES: return '' value = smart_text(value) m = phone_digits_re.match(value) if m: return '%s' % (value) raise ValidationError(self.error_messages['invalid'])
def handle_m2m(value): natural = value.natural_key() # Iterable natural keys are rolled out as subelements self.xml.startElement("object", {}) for key_value in natural: self.xml.startElement("natural", {}) self.xml.characters(smart_text(key_value)) self.xml.endElement("natural") self.xml.endElement("object")
def start_object(self, obj): """ Called as each object is handled. """ if not hasattr(obj, "_meta"): raise base.SerializationError("Non-model object (%s) encountered during serialization" % type(obj)) self.indent(1) obj_pk = obj._get_pk_val() if obj_pk is None: attrs = {"model": smart_text(obj._meta),} else: attrs = { "pk": smart_text(obj._get_pk_val()), "model": smart_text(obj._meta), } self.xml.startElement("object", attrs)
def _get_val(): token = get_token(request) if token is None: # In order to be able to provide debugging info in the # case of misconfiguration, we use a sentinel value # instead of returning an empty dict. return 'NOTPROVIDED' else: return smart_text(token)
def _start_relational_field(self, field): """ Helper to output the <field> element for relational fields """ self.indent(2) self.xml.startElement("field", { "name" : field.name, "rel" : field.rel.__class__.__name__, "to" : smart_text(field.rel.to._meta), })
def clean(self, value): """ Validate a phone number. Strips parentheses, whitespace and hyphens. """ super(AUPhoneNumberField, self).clean(value) if value in EMPTY_VALUES: return '' value = re.sub('(\(|\)|\s+|-)', '', smart_text(value)) phone_match = PHONE_DIGITS_RE.search(value) if phone_match: return '%s' % phone_match.group(1) raise ValidationError(self.error_messages['invalid'])
def clean(self, value): value = super(ITVatNumberField, self).clean(value) if value in EMPTY_VALUES: return '' try: vat_number = int(value) except ValueError: raise ValidationError(self.error_messages['invalid']) vat_number = str(vat_number).zfill(11) check_digit = vat_number_check_digit(vat_number[0:10]) if not vat_number[10] == check_digit: raise ValidationError(self.error_messages['invalid']) return smart_text(vat_number)
def handle_fk_field(self, obj, field): """ Called to handle a ForeignKey (we need to treat them slightly differently from regular fields). """ self._start_relational_field(field) related_att = getattr(obj, field.get_attname()) if related_att is not None: if self.use_natural_keys and hasattr(field.rel.to, 'natural_key'): related = getattr(obj, field.name) # If related object has a natural key, use it related = related.natural_key() # Iterable natural keys are rolled out as subelements for key_value in related: self.xml.startElement("natural", {}) self.xml.characters(smart_text(key_value)) self.xml.endElement("natural") else: self.xml.characters(smart_text(related_att)) else: self.xml.addQuickElement("None") self.xml.endElement("field")
def clean(self, value): # Load data in memory only when it is required, see also #17275 from djangocg.contrib.localflavor.id.id_choices import LICENSE_PLATE_PREFIX_CHOICES super(IDLicensePlateField, self).clean(value) if value in EMPTY_VALUES: return "" plate_number = re.sub(r"\s+", " ", smart_text(value.strip())).upper() matches = plate_re.search(plate_number) if matches is None: raise ValidationError(self.error_messages["invalid"]) # Make sure prefix is in the list of known codes. prefix = matches.group("prefix") if prefix not in [choice[0] for choice in LICENSE_PLATE_PREFIX_CHOICES]: raise ValidationError(self.error_messages["invalid"]) # Only Jakarta (prefix B) can have 3 letter suffix. suffix = matches.group("suffix") if suffix is not None and len(suffix) == 3 and prefix != "B": raise ValidationError(self.error_messages["invalid"]) # RI plates don't have suffix. if prefix == "RI" and suffix is not None and suffix != "": raise ValidationError(self.error_messages["invalid"]) # Number can't be zero. number = matches.group("number") if number == "0": raise ValidationError(self.error_messages["invalid"]) # CD, CC and B 12345 12 if len(number) == 5 or prefix in ("CD", "CC"): # suffix must be numeric and non-empty if re.match(r"^\d+$", suffix) is None: raise ValidationError(self.error_messages["invalid"]) # Known codes range is 12-124 if prefix in ("CD", "CC") and not (12 <= int(number) <= 124): raise ValidationError(self.error_messages["invalid"]) if len(number) == 5 and not (12 <= int(suffix) <= 124): raise ValidationError(self.error_messages["invalid"]) else: # suffix must be non-numeric if suffix is not None and re.match(r"^[A-Z]{,3}$", suffix) is None: raise ValidationError(self.error_messages["invalid"]) return plate_number