[Django]-Test if Django ModelForm has instance

61πŸ‘

βœ…

Try checking if form.instance.pk is None.

hasattr(form.instance, 'pk') will always return True, because every model instance has a pk field, even when it has not yet been saved to the database.

As pointed out by @Paullo in the comments, this will not work if you manually define your primary key and specify a default, e.g. default=uuid.uuid4.

πŸ‘€Alasdair

8πŸ‘

Since the existed instance would be passed as an argument with the keyword instance to create the model-form, you can observe this in your custom initializer.

class Foo(ModelForm):
    _newly_created: bool

    def __init__(self, *args, **kwargs):
        self._newly_created = kwargs.get('instance') is None
        super().__init__(*args, **kwargs)
πŸ‘€WeZZard

4πŸ‘

I encountered this issue but in my case, am using UUID for PK. Though the accepted answer is correct for most cases but fails if you are not using Django default auto increment PK.

Defining a model property gives me the ability to access this value from both, Model, View and Template as attribute of the model

@property
def from_database(self):
    return not self._state.adding
πŸ‘€Paullo

0πŸ‘

I found that self.instance is set in super().init anyway

    class BaseModelForm(BaseForm):
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=ErrorList, label_suffix=None,
                 empty_permitted=False, instance=None, use_required_attribute=None,
                 renderer=None):
...
        if instance is None:
            # if we didn't get an instance, instantiate a new one
            self.instance = opts.model()

https://github.com/django/django/blob/65e03a424e82e157b4513cdebb500891f5c78363/django/forms/models.py#L300

so we can track instance just before super().init called.
So my solution is to override init method and set custom field to track in all followed form’s methods.

    def __init__(self, *args: Any, instance=None, **kwargs: Any) -> None:
    super().__init__(*args, instance=instance, **kwargs)
    self.is_new_instance = not bool(instance)

and usage:

    def _any_form_method(self):
        if self.is_new_instance:

Leave a comment