Skip to content

Improve Optional[] field UX by storing empty value as null instead of showing dropdown to select type #65

@pirate

Description

@pirate

I have a pydantic model like this with a few issues preventing form rendering in the Admin UI:

class Binary(BaseModel):
    model_config = ConfigDict(extra='ignore', populate_by_name=True)

    name: BinName = 'binary-name'  # I wish I could use None here / have no default, but that's also not supported

	# provider_overrides: Dict[str, str] = Field(default={}, alias='overrides') 
	# ^ this also breaks, see separate issue: https://github.com/surenkov/django-pydantic-field/issues/64
    
    loaded_provider: Optional[str] = Field(default=None, alias='provider')
    loaded_abspath: Optional[str] = Field(default=None, alias='abspath')
    
    # loaded_version: Optional[Tuple[int, int, int]] = Field(default=None, alias='version')
    # this also doesn't work: Cannot read properties of undefined (reading 'hasOwnProperty')

When it gets rendered in the Admin UI it looks like this though:
image

I assume because the schema defines two allowed types string and null, so this becomes two "options" in the UI with a dropdown?

Potential solutions:

  1. If the only options are <something> and null (a very common case with Optional[] fields), just show one field in the UI and treat leaving it empty as null
  2. Generate better labels for the options dropdown based on the type, e.g. show string and null instead of Option 1 and Option 2
  3. ⭐️ Show a radio selector to the left of the text field to choose the type, e.g. string/null/int etc. This would allow it to support more Union types than just Optional, as it could swap out the text field widget with widgets for other types depending on which radio button is clicked.

I like option 3 best as it's the most flexible for all Union types, but option 1 may be the least amount of code to implement to just get nullable types working fast.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions