returns a list of (argname, value) tuples (NB: keeps ordering and is easily turned into a dict).
Params:
- tagname : the name of calling tag (for error messages)
- bits : sequence of tokens to parse as kw args
- args_spec : (optional) dict of argname=>validator for kwargs, cf below
- restrict : if True, only argnames in args_specs will be accepted
If restrict=False and args_spec is None (default), this will just try to parse a sequence of key=val strings.
About args_spec validators :
- A validator can be either a callable, a regular expression or None.
- If it's a callable, the callable must take the value as argument and return a (possibly different) value, which will become the final value for the argument. Any exception raised by the validator will be considered a rejection.
- If it's a regexp, the value will be matched against it. A failure will be considered as a rejection.
- Using None as validator only makes sense with the restrict flag set to True. This is useful when the only validation is on the argument name being expected.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | def parse_kw_args(tagname, bits, args_spec=None, restrict=False):
""" keywords arguments parser for template tags
returns a list of (argname, value) tuples
(NB: keeps ordering and is easily turned into a dict).
Params:
* tagname : the name of calling tag (for error messages)
* bits : sequence of tokens to parse as kw args
* args_spec : (optional) dict of argname=>validator for kwargs, cf below
* restrict : if True, only argnames in args_specs will be accepted
If restrict=False and args_spec is None (default), this will just try
to parse a sequence of key=val strings into a
About args_spec validators :
* A validator can be either a callable, a regular expression or None.
* If it's a callable, the callable must take the value as argument and
return a (possibly different) value, which will become the final value
for the argument. Any exception raised by the validator will be
considered a rejection.
* If it's a regexp, the value will be matched against it. A failure
will be considered as a rejection.
* Using None as validator only makes sense with the restrict flag set
to True. This is useful when the only validation is on the argument
name being expected.
"""
args = []
if restrict:
if args_spec is None:
raise ValueError("you must pass an args_spec dict if you want to restrict allowed args")
allowed = list(args_spec.keys())
do_validate = True
else:
do_validate = args_spec is not None
for bit in bits:
try:
name, val = bit.split('=')
except ValueError:
raise template.TemplateSyntaxError(
"keyword arguments to '%s' tag must have 'key=value' form (got : '%s')" \
% (tagname, bit)
)
name = str(name)
if do_validate:
if restrict:
if name in allowed:
# we only want each name once
del allowed[allowed.index(name)]
else:
raise template.TemplateSyntaxError(
"keyword arguments to '%s' tag must be one of % (got : '%s')" \
% (tagname, ",".join(allowed), name)
)
validate = args_spec[name]
else:
validate = args_spec.get(name, None)
if validate is not None:
if callable(validate):
try:
val = validate(val)
except Exception, e:
raise template.TemplateSyntaxError(
"invalid optional argument '%s' for '%s' tag: '%s' (%s)" \
% (tagname, name, val, e)
)
else:
# assume re
if re.match(validate, val) is None:
raise template.TemplateSyntaxError(
"invalid optional argument '%s' for '%s' tag: '%s' (doesn't match '%s')" \
% (tagname, name, val, validate)
)
# should be ok if we managed to get here
args.append((name, val))
return args
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
NB : Fixed a problem with indentation (validation callback was not called when restrict==True)
#
del allowed[allowed.index(name)]
should be written asallowed.remove(name)
#
Please login first before commenting.