2015-01-08 9 views
15

In Django sono presenti due modelli correlati a OneToOneField (PrinterProfile e PrinterAdress). Sto cercando di creare un modulo con PrinterProfileForm, ma per qualche motivo NON passa i campi PrinterAddress nel modulo (non è reso da Django "magic" nel modello).ModelForm con OneToOneField in Django

Cosa devo fare affinché il mio PrinterProfileForm includa anche i campi da PrinterAddress (relativo OneToOneField)?

Grazie mille

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'] 

risposta

24

È necessario creare seconda forma per PrinterAddress e gestire entrambe le forme in te 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() 

Naturalmente nel modello è necessario mostrare entrambe le forme sotto un unico <form> tag :-)

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

grazie mille! Life-saver ... Qualche idea sul perché non è stata presa automaticamente da Django ModelForm? È una decisione di progettazione o una specie di bug? Grazie – cyberjoac

+0

Questa è la decisione di progettazione. Vi sono molte insidie ​​nella gestione di più di un modello in un'unica forma (ad esempio: come gestire le relazioni tra modelli, come gestire campi con lo stesso nome in diversi modelli, come impostare campi aggiuntivi al di fuori del modulo). – catavaran

+0

Ha senso, anche se capisco che funzioni con ForeignKeys (inline_formset), quindi qual è la differenza con onetooneField? Mi sembra meno difficile, vero? – cyberjoac

0

A complemento del accepted answer:

Se si dispone di metodi puliti personalizzati, è necessario aggiungere un caso try/except. Per l'esempio presentato se address avuto un metodo clean() per convalidare qualcosa bisognava cambiarlo in:

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