Django 中带有 OneToOneField 的 ModelForm
ModelForm with OneToOneField in Django
我在 Django 中有两个模型与 OneToOneField
(PrinterProfile
和 PrinterAdress
)相关。
我正在尝试使用 PrinterProfileForm
创建一个表单,但由于某种原因它没有将 PrinterAddress
字段传递到表单中(它不是由模板中的 Django "magic" 呈现的)。
我应该怎么做才能让我的 PrinterProfileForm
也包括来自 PrinterAddress
的字段(它的相关 OneToOneField
)?
非常感谢
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
创建第二个表单并在您的视图中处理这两个表单:
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()
当然,在模板中,您需要在一个 <form>
标签下显示两种形式 :-)
<form action="" method="post">
{% csrf_token %}
{{ profile_form }}
{{ address_form }}
</form>
补充:
如果您有自定义清理方法,则需要添加一个 try/except
案例。对于所提供的示例,如果 address
有一个 clean()
方法来验证您需要将其更改为的内容:
def clean(self):
try:
printer_profile = self.printer_profile
except ObjectDoesNotExist:
pass
else:
...code to validate address...
我在 Django 中有两个模型与 OneToOneField
(PrinterProfile
和 PrinterAdress
)相关。
我正在尝试使用 PrinterProfileForm
创建一个表单,但由于某种原因它没有将 PrinterAddress
字段传递到表单中(它不是由模板中的 Django "magic" 呈现的)。
我应该怎么做才能让我的 PrinterProfileForm
也包括来自 PrinterAddress
的字段(它的相关 OneToOneField
)?
非常感谢
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
创建第二个表单并在您的视图中处理这两个表单:
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()
当然,在模板中,您需要在一个 <form>
标签下显示两种形式 :-)
<form action="" method="post">
{% csrf_token %}
{{ profile_form }}
{{ address_form }}
</form>
补充
如果您有自定义清理方法,则需要添加一个 try/except
案例。对于所提供的示例,如果 address
有一个 clean()
方法来验证您需要将其更改为的内容:
def clean(self):
try:
printer_profile = self.printer_profile
except ObjectDoesNotExist:
pass
else:
...code to validate address...