Optional/required
Unlike with querying values you can, but don't need to specify whether elements queried from the document are optional or required. As you will most often use the elements' values themselves, the necessity for the element hierarchy in between the document and that value is automatically inferred by whether the value itself is optional or required:
document.section('content').section('translated').field('revision').optional_string_value()
The line above can be run for an entirely empty document and still return None
, while by
modifying the query of the value itself to be required would make the code raise an error for
the first element missing in that hierarchy instead (again assuming an empty document):
document.section('content').section('translated').field('revision').required_string_value()
This would produce an error:
The section 'content' is missing - in case it has been specified look for typos and also check for correct capitalization.
Line | Content
* 1 |
With that said, there will of course also be cases where you want to be explicit
about whether an element is optional or required, for this you can use the
explicit optional_*
or required_*
accessor variant, which exists for all
element types, for instance:
document.required_field('author')
document.optional_section('notes')
As with value accessors, the optional_*
variants return None
if the element
does not exist (be aware that you should not chain further queries after such a
call because you'd potentially be calling a function on None
), while the required_*
variants immediately raise an error when the element is missing (here you can safely chain further queries afterwards).
Below is a pattern you might find useful, it's basically saying "There always has to
be a field with the key 'author', but it can be empty". It returns None
or the value,
and only raises an error when the field itself is missing.
document.required_field('author').optional_string_value()
The pattern below is sort of the reverse, it's "If there is a field with the key 'author', it also requires a value", and guarantees there is a value if there is also a field, otherwise an error is raised.
author = document.optional_field('author')
if author:
value = author.required_string_value()
# ...
Last but not least a pattern that does not work:
author = document.field('author')
if author:
# Will always enter here, author is never None
As shown earlier you can safely and deeply query a non-existing document
hierarchy. This is possible because the standard query methods return proxy
objects (e.g. MissingSection
) instead of None
when an element in the chain
is missing, and with that it's clear why the previous example does not work,
instead you have to use the explicit optional_field
accessor to ensure you are
being returned None
if there is no element.
author = document.optional_field('author')
if author:
# This works, author can be None now
Next page: Dynamic layouts