Skip to content

MagiForm

deby edited this page Feb 23, 2022 · 9 revisions

↑ Parent: Collections

← Previous: MagiCollection

Default

By default, edit forms will automatically detect which fields to display, which widget should be used for each and whether or not it's required.

Customize form

To customize the form that will be used when adding and editing an item, you can create your own form class.

Your class must inherit from AutoForm (recommended, lists all the fields for you) or MagiForm (you need to list the fields you want to use).

${PROJECT}/magicollections.py:

from . import forms

class CardCollection(MagiCollection):
    ...
    form_class = forms.CardForm

${PROJECT}/forms.py:

from django import forms
from magi.forms import AutoForm

class CardForm(AutoForm):
    class Meta(AutoForm):
        model = models.Card

Hide portions of the form by default

If you have a lot of fields, including some that rarely get changed or are changed automatically by some API and rarely by users, you may want to hide them by default, and show a button to show them.

Example:

show more field

${PROJECT}/form.py:

from magi.utils import FormShowMore

class CardForm(AutoForm):
    ...
    show_more = FormShowMore(cutoff='image', including_cutoff=False, until='role')

It's possible to hide multiple portions by providing a list of FormShowMore in the show_more variable.

All settings available documented in MagiForm settings.

Show/hide fields based on other field

This example shows "gacha type" only if "origin" has a value (regardless of what is the value):

${PROJECT}/form.py:

class CardForm(AutoForm):
    ...
    on_change_value_show = {
        'origin': ['gacha_type'],
    }

This example shows "gacha type" only if the value of "origin" is "gacha":

${PROJECT}/form.py:

class CardForm(AutoForm):
    ...
    on_change_value_show = {
        'origin': {
            'gacha': ['gacha_type'],
            'event': ['event_type', 'event_score'],
        },
    }

How to represent values for specific form field types:

  • i choices: { 'cloud': [...], 'sun': [...] } or { 1: [...], 2: [...] }
  • Checkbox: { True: [...], False: [...] }
  • Null boolean: { None: [...], True: [...], False: [...] }
  • Multi choices: { 'a,b,c': [...] } (note: exact match only, including order of fields)
  • c choices: { 'cloud': [...], 'sun': [...] }

Dynamic changes on initialization

If you want to add some extra logic at the initialization of the form, you can override __init__:

class CardForm(AutoForm):
    def __init__(self, *args, **kwargs):
        super(CardForm, self).__init__(*args, **kwargs)
        self.fields['skill_details'].label = _('Skill details')
    ...

Dynamic changes before saving the instance

If you want to add some extra logic before saving the item in the database, you can override save:

class CardForm(AutoForm):
    def save(self, commit=False):
	instance = super(CardForm, self).save(commit=False)
        instance.score = instance.score / 100
        if commit:
            instance.save()
        return instance
    ...

If you want to do something depending on a specific field that changed, you can save the previous value in __init__ and add your logic in save. This can be useful to update cached foreign keys.

class CardForm(AutoForm):
    def __init__(self, *args, **kwargs):
        super(CardForm, self).__init__(*args, **kwargs)
        self.previous_member_id = None if self.is_creating else self.instance.member_id

    def save(self, commit=False):
        instance = super(CardForm, self).save(commit=False)
        if self.previous_member_id != instance.member_id:
            instance.update_cache_member()
        if commit:
            instance.save()
        return instance

    ...

⚠️ If some of the logic needs to be done after the instance has been saved, then you should use after_save in MagiCollection or within each view instead.

Example: updating a cache

DateTime fields

By default, if you have a DateTimeField in your model, the form will only allow to change the date and not the time. It will then default to midnight UTC. You can set a default time in the code, or allow users to enter time in the form.

ℹ︎ See: DateTime fields

ℹ︎ See also: MagiForm settings

→ Next: MagiFiltersForm

I. Introduction

II. Tutorials

  1. Collections
    1. MagiModel
    2. MagiCollection
    3. MagiForm
    4. MagiFiltersForm
    5. MagiFields
  2. Single pages
  3. Configuring the navbar

III. References

IV. Utils

V. Advanced tutorials

VI. More

Clone this wiki locally