Not sure about the best or canonical solution but at least in DX behaviors I frequently use the following pattern:
It allows me to assign DX fields as property with custom getter/setter methods and in my case with fixed default values. I assume that you can extend the getter implementation easily with support for default methods.
There is likely something in the plone.supermodel - I remember having used a default method once but on the XML level of a model.
This has the advantage of not being tied to a particular form library, as well as being the most readable solution proposed. Dexterity's __getattr__ is aware of defaultFactory and will calculate the default if you try to fetch an attribute that doesn't have a value stored. (So beware; if you don't set a value then you'll get a new date if you access the default again tomorrow.)
You can also use <defaultFactory>dotted.path.to.factory</defaultFactory> in an XML supermodel, as long as the factory provides the plone.supermodel.interfaces.IDefaultFactory marker interface (for security to make sure that TTW schema editors can't reference arbitrary Python functions).