This document compares features in PartisipaNodePath with the base FormKit generator to identify what's available and what could be enhanced.
- Status: ✅ Available as extension point
- Base Implementation: Returns
"SubStatusFilter"by default - Partisipa Override: Returns different filter classes based on
classname(e.g.,SubstatusYearSucoFilter,PriorityFilter,RepeaterSubStatusFilter) - Location:
formkit_ninja/parser/type_convert.py:505-515
- Status: ✅ Available as extension point
- Base Implementation: Returns empty list
[] - Partisipa Override: Adds
OneToOneFieldtoSubmissionfor depth=1 nodes - Location:
formkit_ninja/parser/type_convert.py:457-463 - Used in:
templates/model.jinja2
- Status: ✅ Available as extension point
- Base Implementation: Returns empty list
[] - Partisipa Override: Adds
submission_id: UUIDfor depth=1 nodes - Location:
formkit_ninja/parser/type_convert.py:465-471 - Used in:
templates/schema.jinja2
- Status: ✅ Available as extension point
- Base Implementation: Returns empty list
[] - Partisipa Override: Adds
id: UUIDandform_type: Literal[...]for depth=1 nodes - Location:
formkit_ninja/parser/type_convert.py:473-479 - Used in:
templates/basemodel.jinja2
- Status: ✅ Available as extension point via
get_validators() - Base Implementation: Returns empty list
[] - Partisipa Override: Adds validators for
date_type andlatitude/longitudefields - Location:
formkit_ninja/parser/type_convert.py:481-502 - Used in:
templates/basemodel.jinja2
- Status: ✅ Available as extension point
- Base Implementation: Returns empty list
[] - Location:
formkit_ninja/parser/type_convert.py:529-539 - Used in:
templates/models.py.jinja2
- Status: ✅ Available
- Location:
formkit_ninja/parser/type_convert.py:306-312 - Used in:
templates/model.jinja2,templates/abstract_model.jinja2
- Status: ✅ Available
- Location:
formkit_ninja/parser/type_convert.py:294-304 - Used in: Templates for inline comments showing field source
- Status:
⚠️ Can be overridden, but logic is complex - Base Implementation: Uses
TypeConverterRegistryfor formkit-based conversion, falls back to hardcoded logic - Partisipa Override:
- Checks
node.optionsfor specific patterns ($getoptions...,$ida(yesno)) - Checks
node.namefor specific field names (e.g.,district,latitude,activity_type) - Uses
_ida_modelhelper property
- Checks
- Challenge: Base implementation uses registry for
formkitattribute, but Partisipa needs to checkoptionsandnameattributes - Location:
formkit_ninja/parser/type_convert.py:333-376
- Status:
⚠️ Can be overridden, but logic is complex - Base Implementation: Maps pydantic types to Django field types
- Partisipa Override:
- Checks
_ida_modelto returnForeignKey - Checks
node.namefor specific fields (e.g.,district,latitude) to returnForeignKeyorDecimalField - Checks
to_pydantic_type() == "date_"to returnDateField
- Checks
- Location:
formkit_ninja/parser/type_convert.py:400-424
- Status:
⚠️ Can be overridden, but logic is complex - Base Implementation: Returns standard Django field arguments based on pydantic type
- Partisipa Override:
- Custom
max_digits/decimal_placesforDecimalfields (12 places for lat/long, 2 for currency) - Custom args for
UUIDfields (editable=False, unique=True) - Adds model references for
ForeignKeyfields (IDA models vs zTables) - Custom
on_deletebehavior (DO_NOTHINGfor IDA,CASCADEfor zTables) - Special
related_name="+"forYesNomodel
- Custom
- Location:
formkit_ninja/parser/type_convert.py:430-451
- Status: ❌ Partisipa-specific helper
- Purpose: Extracts model name from
$ida(...)option strings - Note: This is domain-specific to Partisipa's IDA options system
- Could be: Made into an extension point if other projects need similar functionality
All the extension point properties (filter_clause, extra_attribs*, validators, get_custom_imports()) are already available and work as designed. PartisipaNodePath can simply override these.
The type conversion methods (to_pydantic_type(), to_django_type(), to_django_args()) require full method override because:
- Base implementation primarily uses
formkitattribute via registry - Partisipa needs to check
node.optionsandnode.nameattributes - Partisipa has domain-specific logic (IDA models, zTables, field name mappings)
-
Enhanced Type Converter Registry
- Allow converters to check
node.optionsandnode.name, not justformkittype - Support "field name based" converters (e.g., "if name == 'district', return ForeignKey")
- Support "option pattern based" converters (e.g., "if options starts with '$ida(', return int")
- Allow converters to check
-
Extension Point for Django Args
- Add
get_django_args_extra()method that returns additional args to append - This would allow Partisipa to add IDA/zTable model references without full override
- Add
-
Helper Property Extension Points
- Make
_ida_modelpattern into a genericget_related_model()extension point - Allow subclasses to return related model info for ForeignKey generation
- Make
-
Node Attribute Access Helpers
- Add convenience methods like
has_option(pattern),get_option_value(),matches_name(names) - These would make overrides cleaner and more maintainable
- Add convenience methods like
The base FormKit generator already provides excellent extension points for most customization needs. The main gap is in type conversion flexibility - the current system is optimized for formkit-based conversion, but Partisipa needs options and name-based logic. This could be addressed by:
- Enhancing the TypeConverterRegistry to support multi-attribute matching
- Adding more granular extension points for Django field arguments
- Providing helper methods for common node attribute checks
However, the current approach (subclassing and overriding) works perfectly fine and is a valid design choice.