ModelForm with OneToOneField in Django

Complementing the accepted answer:

If you have custom clean methods, you need to add a try/except case. For the example presented if address had a clean() method to validate something you needed to change it to:

def clean(self):
    try:
        printer_profile = self.printer_profile 
    except ObjectDoesNotExist:
        pass
    else:
        ...code to validate address...

You have to create second form for PrinterAddress and handle both forms in you view:

if all((profile_form.is_valid(), address_form.is_valid())):
    profile = profile_form.save()
    address = address_form.save(commit=False)
    address.printer_profile = profile
    address.save()

Of course in the template you need to show both forms under one <form> tag :-)

<form action="" method="post">
    {% csrf_token %}
    {{ profile_form }}
    {{ address_form }}
</form>