Forms, fields and widgets#

The core app ships a handful of forms reused across the project, plus the supporting custom field and widgets they rely on.

Forms#

SearchForm#

The form behind the top-bar / sidebar search. A single query text field with autocomplete disabled (so the browser doesn’t shadow the in-app suggestion UI).

class richy.core.forms.SearchForm(*args, **kwargs)[source]#

Bases: Form

BaseUserItemForm#

Base ModelForm for editing a UserItem. Each per-app item edit form (shares, etfs, indexes, coins) inherits from this base and supplies its own item_model – the form drives the symbol input, custom-index assignment, archive flag and free-form note.

Constructor takes the current user: the indexes queryset is scoped to that user’s indexes, and form-level validation enforces:

  • For new items, the symbol cannot collide with an item the user already has.

  • For existing items, the symbol field becomes read-only.

  • Symbols are stored uppercase regardless of input casing.

  • An item with an open Transaction cannot be archived.

class richy.core.forms.BaseUserItemForm(user, *args, **kwargs)[source]#

Bases: ModelForm

BaseUserItemForm.clean_symbol()[source]#

Converts symbol to UPPERCASE.

Returns:

Uppercased symbol.

Return type:

str

BaseUserItemForm.clean_is_archived()[source]#

Checks if item can be archived or not.

Raises:

ValidationError – In case when item cannot be archived.

Returns:

Archived flag value.

Return type:

bool

SplitterForm#

The form behind the splitter tool: applies a stock split (or reverse split) retroactively to historical prices of an item. Takes the concrete item model class at construction time (so the item queryset can be narrowed to the right asset type).

Fields: item, date (the split date), ratio.

class richy.core.forms.SplitterForm(model, *args, **kwargs)[source]#

Bases: Form

SplitterPreviewForm#

Intentionally empty – the splitter preview view uses this only to mark its second step in the flow (the actual data comes from the preceding SplitterForm submission).

class richy.core.forms.SplitterPreviewForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)[source]#

Bases: Form

Fields#

MultipleFileField#

A file field with multiple upload turned on (the user can pick several files from disk). Once uploaded, files can be removed and more files added.

The initial data is a list of model instances representing the file records in the database. The model must expose a file property (either a real model field or a @property-aliased method). The widget uses the model PK in URLs for deletion.

The field extends from FileField and is paired with MultipleFileInput.

Special properties:

  • delete_url_pattern – URL pattern where the deletion URL points to; must contain an id URL parameter.

class richy.core.fields.MultipleFileField(delete_url_pattern=None, *args, **kwargs)[source]#

Bases: FileField

Widgets#

MultipleFileInput#

The widget paired with MultipleFileField. Extends Django’s ClearableFileInput with allow_multiple_selected = True and renders through the custom template widgets/clearable_multiple_file.html so the existing attachments and the delete links are visible alongside the file picker.

class richy.core.widgets.MultipleFileInput(*args, **kwargs)[source]#

Bases: ClearableFileInput

NoLabelCheckboxSelectMultiple#

Variant of Django’s CheckboxSelectMultiple that swaps the option template from django/forms/widgets/input_option.html to django/forms/widgets/input.html – effectively skipping the per-option <label> rendering. Used where the label belongs to the surrounding markup rather than each individual checkbox.

class richy.core.widgets.NoLabelCheckboxSelectMultiple(attrs=None, choices=())[source]#

Bases: CheckboxSelectMultiple

In hierarchy of templates skips input_option.html widget template which handles label rendering.