2

I have two models inn my django application where I have ManyToMany field in one model to other. I want to set the default for ManyToMany field but getting no way to do this.
My models are

Class Model1(models.Model):
    name = models.CharField(max_length=100)

class Model2(models.Model):
    model1 = models.ManyToManyField(Model1, null=True, blank=True, default=Model1.objects.first())

but using this I am getting this error

    raise AppRegistryNotReady("Models aren't loaded yet.")
    django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.

I tried it by defining an explicit variable also like

m1 = Model1.objects.first()
and assigning this m1 variable to the field as default but same error again.

Please suggest how can I assign default value to the M2Mfield in django. I want that the first object of the choices should be selected when the modelform renders on template.

Sajid Ahmad
  • 1,124
  • 4
  • 18
  • 40

1 Answers1

1

Given the way Django parses model class, you cannot do it like that, because "Models aren't loaded yet" <=> default are set at "parse time"

But you could use a callable as default.

def get_first_model1():
    return Model1.objects.first()

class Model2(models.Model):
    model1 = models.ManyToManyField(Model1, null=True, blank=True, default=get_first_model1)

It's the callable that you should use not the result value, thus the lack of parenthesis.

With this modification, default callable will be called at execution time when creating a new Model2 if you do not provide model1 attribute value.

Raphaël Braud
  • 1,489
  • 10
  • 14
  • 1
    The given solution works to an extent. It doesn't give me the `models are not loaded yet` error but in template it gives error `'int' object is not iterable` and on terminal there is an error ` selected_choices = set(force_text(v) for v in selected_choices) TypeError: 'int' object is not iterable` – Sajid Ahmad Mar 27 '15 at 14:03
  • code can be used to set default for newly created objects. Regarding forms, maybe this post can be helpful : http://stackoverflow.com/questions/604266/django-set-default-form-values – Raphaël Braud Mar 27 '15 at 14:10
  • 2
    I think the default value for a M2M field should be a list of `pk`, so instead of `return Model1.objects.first()` try `return [Model1.objects.first().pk]` – Todor Mar 28 '15 at 04:56
  • I know this is old, but I stumbled onto this and [that (old and "unresolved") ticket](https://code.djangoproject.com/ticket/2750) while looking for something similar. Hope this will save some time to somebody : django doesn't seems to behaved as expected with the 'default' for ManyToManyField... I had to use the [post_save](https://docs.djangoproject.com/en/dev/ref/signals/#post-save) signal as suggested in [this comment](https://stackoverflow.com/questions/31617838/django-manytomany-all-values-by-default#comment-51185589). – tgrandje Sep 16 '20 at 12:08