Question: I have the following code:

```
class Album(models.Model):
  name = models.CharField(max_length=255, unique=True, null=False)
  rating = models.ForeignKey("Rating", null=False)

class Rating(models.Model):
  value = models.IntegerField(null=False, default=0)

```

What is the best way (in the django/python philosophy) to create an object (Album) and it's sub object (Rating) and save it?

I have done this:

```
a = Album()
a.name = "..."
r = Rating()
r.save()
a.rating = r
a.save()

```

I don't like this because the part of creating the sub object empty is totally not useful.
I'd prefer some simple way like this - the sub-object should be created automatically:

```
a = Album()
a.name = "..."
a.save()

```

Answer: 
You'll want to look into [`signals`](https://docs.djangoproject.com/en/1.4/topics/signals/).

Essentially a signals are sent when an Object is saved.

Using a [`pre_save`](https://docs.djangoproject.com/en/dev/ref/signals/#pre-save) signal you can then create a `Rating` and associate it to the new `Album` jsut before it is saved for the first time.

```
from django.db.models.signals import pre_save
from django.dispatch import receiver
from myapp.models import Album, Rating

@receiver(pre_save, sender=Album)
def add_rating_to_album(sender, **kwargs):

    # If saving a new Album
    if not instance.id:

        # Create and save a new rating
        rating = Rating()
        rating.save()

        # Associate it to the Album being saved
        instance.rating = rating

    # Continue to normal save with new rating applied

```

*I haven't tested this specific code but it should get you in the right direction*
Using signals as rockingskier said is a nice way to do it because your Album objects does not have to know anything about Rating so it gains independence.

Another way to do it would be to override the method `save` of Album and create the new Rating object there, this code is based on the example in [Django docs](https://docs.djangoproject.com/en/1.4/topics/db/models/#overriding-model-methods):

```
class Album(models.Model):
    name = models.CharField(max_length=100)

def save(self, *args, **kwargs):
    # do something here
    super(Album, self).save(*args, **kwargs) # Call the "real" save() method.
    # do anything else

```

This may be a simpler way to do it but your Album model would be tied to your Rating model.