2015-01-08 29 views
15

Tôi có hai mô hình trong Django có liên quan với OneToOneField (PrinterProfile và PrinterAdress). Tôi đang cố gắng để làm một biểu mẫu với PrinterProfileForm, nhưng vì một số lý do nó không vượt qua các lĩnh vực PrinterAddress vào mẫu (nó không được trả lại bởi Django "ma thuật" trong mẫu).ModelForm với OneToOneField ở Django

Tôi nên làm gì để PrinterProfileForm của tôi cũng bao gồm các trường từ PrinterAddress (OneToOneField liên quan của nó)?

Thanks a lot

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

Trả lời

24

Bạn phải tạo hình thức thứ hai cho PrinterAddress và xử lý cả hai hình thức trong bạn xem:

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() 

Tất nhiên trong các mẫu bạn cần phải chứng minh cả hai hình thức dưới một <form> thẻ :-)

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

Cảm ơn bạn rất nhiều! Life-saver ... Bất kỳ ý tưởng tại sao nó không được chăm sóc tự động bởi Django ModelForm? Đây có phải là một quyết định thiết kế hay một loại lỗi nào đó không? Cảm ơn – cyberjoac

+0

Đây là quyết định thiết kế. Có rất nhiều cạm bẫy trong việc xử lý nhiều mô hình dưới dạng đơn (ví dụ: cách xử lý quan hệ mô hình, cách xử lý các trường có cùng tên trong các mô hình khác nhau, cách đặt trường bổ sung bên ngoài biểu mẫu). – catavaran

+0

Làm cho tinh thần, mặc dù tôi hiểu rằng nó hoạt động với ForeignKeys (inline_formset), do đó, sự khác biệt với onetooneField là gì? Nghe có vẻ khó khăn hơn với tôi, phải không? – cyberjoac

0

Bổ sung accepted answer:

Nếu bạn có phương thức làm sạch tùy chỉnh, bạn cần thêm trường hợp try/except. Đối với ví dụ được trình bày nếu address đã có một phương pháp clean() để xác nhận một cái gì đó bạn cần phải thay đổi nó để:

def clean(self): 
    try: 
     printer_profile = self.printer_profile 
    except ObjectDoesNotExist: 
     pass 
    else: 
     ...code to validate address... 
Các vấn đề liên quan