ModelForm con OneToOneField en Django
one-to-one django-forms (2)
Complementando la respuesta aceptada :
Si tiene métodos de limpieza personalizados, debe agregar un caso try/except
. Para el ejemplo presentado, si la address
tenía un método clean()
para validar algo, necesitaba cambiarlo a:
def clean(self):
try:
printer_profile = self.printer_profile
except ObjectDoesNotExist:
pass
else:
...code to validate address...
Tengo dos modelos en Django que están relacionados con OneToOneField (PrinterProfile y PrinterAdress). Estoy intentando hacer un formulario con PrinterProfileForm, pero por alguna razón NO pasa los campos de Dirección de Impresora al formulario (no está representado por Django "magic" en la plantilla)
¿Qué debo hacer para que mi PrinterProfileForm incluya también los campos de PrinterAddress (su OneToOneField relacionado)?
Muchas gracias
class PrinterProfile(TimeStampedModel):
user = models.OneToOneField(User)
phone_number = models.CharField(max_length=120, null=False, blank=False)
additional_notes = models.TextField()
delivery = models.BooleanField(default=False)
pickup = models.BooleanField(default=True)
# The main address of the profile, it will be where are located all the printers.
class PrinterAddress(TimeStampedModel):
printer_profile = models.OneToOneField(PrinterProfile)
formatted_address = models.CharField(max_length=200, null=True)
latitude = models.DecimalField(max_digits=25, decimal_places=20) # NEED TO CHECK HERE THE PRECISION NEEDED.
longitude = models.DecimalField(max_digits=25, decimal_places=20) # NEED TO CHECK HERE THE PRECISION NEEDED.
point = models.PointField(srid=4326)
def __unicode__(self, ):
return self.user.username
class PrinterProfileForm(forms.ModelForm):
class Meta:
model = PrinterProfile
exclude = [''user'']
PrinterAddress
crear un segundo formulario para PrinterAddress
y manejar ambos formularios en la vista:
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()
Por supuesto, en la plantilla debe mostrar ambos formularios bajo una etiqueta <form>
:-)
<form action="" method="post">
{% csrf_token %}
{{ profile_form }}
{{ address_form }}
</form>