Can Django automatically create a related one-to-one model? Can Django automatically create a related one-to-one model? django django

Can Django automatically create a related one-to-one model?


Take a look at the AutoOneToOneField in django-annoying. From the docs:

from annoying.fields import AutoOneToOneFieldclass MyProfile(models.Model):    user = AutoOneToOneField(User, primary_key=True)    home_page = models.URLField(max_length=255)    icq = models.CharField(max_length=255)

(django-annoying is a great little library that includes gems like the render_to decorator and the get_object_or_None and get_config functions)


Like m000 pointed out:

... The catch in the question is that the models belong to different apps. This matches the use case for signals: "allow decoupled applications get notified when actions occur elsewhere in the framework". Other proposed solutions work but introduce an unnecessary A->B dependency, essentially bundling the two apps. Signals allows A to remain decoupled from B.

Your models exist in different apps. Often you use apps you didn't write, so to allow updates you need a decoupled way to create logically related models. This is the preferred solution in my opinion and we use it in a very large project.

By using signals:

In your models.py:

from django.db.models import signalsdef create_model_b(sender, instance, created, **kwargs):    """Create ModelB for every new ModelA."""    if created:        ModelB.objects.create(thing=instance)signals.post_save.connect(create_model_b, sender=ModelA, weak=False,                          dispatch_uid='models.create_model_b')

You can create a separate app to hold this models.py file if both of the apps are off-the-shelf.


The most straightforward way is to override the save method of ModelA:

class ModelA(models.Model):    name = models.CharField(max_length=30)    def save(self, force_insert=False, force_update=False):        is_new = self.id is None        super(ModelA, self).save(force_insert, force_update)        if is_new:            ModelB.objects.create(thing=self)