将模型 属性 值发送到其他模型并以其形式显示
Send model property value to other model and display it in it's form
我正在开发一个应用程序,用户将在其中填写模型的第一个表单,他将被重定向到下一个表单,我想从第一个模型的 属性 中获取值传递给第二个模型并以其形式显示。
***Models***
class Delivery(models.Model):
user = models.ForeignKey(
Client, on_delete=models.CASCADE, verbose_name=_("Client"), related_name=_("delivery_user")
)
pickup_address = models.ForeignKey(Address, on_delete=models.CASCADE, related_name=_("pickup_address"))
destination_address = models.ForeignKey(Address, on_delete=models.CASCADE, related_name=_("destination_address"))
operation_date = models.DateField(
_("desired pickup date"), auto_now=False, auto_now_add=False, blank=False, null=False
)
invoice = models.BooleanField(_("check if you want an invoice"), default=False)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True, editable=False)
updated_at = models.DateTimeField(_("Updated at"), auto_now=True)
delivery_key = models.CharField(max_length=200)
@property
def distance(self):
distance = Distance(
m=self.pickup_address.address_point.transform(32148, clone=True).distance(
self.destination_address.address_point.transform(32148, clone=True)
)
)
context = {}
context["distance"] = f"{round(distance.m / 1000, 2)}"
print(context)
return context
def __str__(self):
return str(self.delivery_key)
class DeliveryDetails(models.Model):
delivery = models.ForeignKey(Delivery, on_delete=models.CASCADE, related_name=_("delivery"))
distance = models.DecimalField(_("Distance Approximative "), max_digits=7, decimal_places=2)
delivery_price = models.DecimalField(max_digits=7, decimal_places=2)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True, editable=False)
updated_at = models.DateTimeField(_("Updated at"), auto_now=True)
def __str__(self):
return str(self.created_at)
***Views***
class DeliveryCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView, FormView):
model = Delivery
form_class = UserDeliveryForm
template_name = "deliveries/customer/edit_deliveries.html"
def get_success_url(self):
return reverse(
"delivery:delivery-details",
kwargs={"pk": self.object.pk, "distance": self.object.distance},
)
def test_func(self):
return self.request.user.is_active
class DetailsDeliveryCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView, FormView):
model = DeliveryDetails
form_class = DeliveryDetailsForm
template_name = "deliveries/responsable/edit_deliveries_details.html"
success_url = reverse_lazy("account:dashboard")
def test_func(self):
return self.request.user.is_active
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
delivery = Delivery.objects.filter(id=self.kwargs["pk"])
context["form"].fields["delivery"].queryset = delivery
distance = Delivery.objects.get(id=self.kwargs["pk"]).distance["google_distance"]
return context
有没有办法在 DetailleDelivery 中获取 Delivery 实例(发票键和距离)并在用户填写 DeliveryDetailsForm 时将它们显示给用户?
如果可能的话,我想避免多次访问数据库以获得相同的数据。
在您的 DetailsDeliveryCreateView
中设置表单初始值:
def get_initial(self):
initial = super(DetailsDeliveryCreateView, self).get_initial()
initial = initial.copy()
delivery = Delivery.objects.get(id=self.kwargs["pk"])
distance = delivery.distance["google_distance"]
initial['distance'] = delivery
initial['distance'] = distance
return initial
您可以将传递传递到上下文中,如下所示:
上下文 ['delivery'] = 交付
然后在您的模板中,您可以使用 {{delivery.distance}} 以及您需要的任何其他内容。您将拥有整个对象。
显然这仅适用于相关父对象尚不存在的创建视图。在详细视图中,您可以通过子项访问父项。
此外,您可能希望使用 get_object_or_404 而不是过滤器来获取您的 Delivery 实例,以防有人尝试不存在的 pk。
此外,如果有意义的话,不要在表格中插入您的交付,只需将其完全关闭并覆盖您的 form_valid() 以在保存之前插入交付关系。
我正在开发一个应用程序,用户将在其中填写模型的第一个表单,他将被重定向到下一个表单,我想从第一个模型的 属性 中获取值传递给第二个模型并以其形式显示。
***Models***
class Delivery(models.Model):
user = models.ForeignKey(
Client, on_delete=models.CASCADE, verbose_name=_("Client"), related_name=_("delivery_user")
)
pickup_address = models.ForeignKey(Address, on_delete=models.CASCADE, related_name=_("pickup_address"))
destination_address = models.ForeignKey(Address, on_delete=models.CASCADE, related_name=_("destination_address"))
operation_date = models.DateField(
_("desired pickup date"), auto_now=False, auto_now_add=False, blank=False, null=False
)
invoice = models.BooleanField(_("check if you want an invoice"), default=False)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True, editable=False)
updated_at = models.DateTimeField(_("Updated at"), auto_now=True)
delivery_key = models.CharField(max_length=200)
@property
def distance(self):
distance = Distance(
m=self.pickup_address.address_point.transform(32148, clone=True).distance(
self.destination_address.address_point.transform(32148, clone=True)
)
)
context = {}
context["distance"] = f"{round(distance.m / 1000, 2)}"
print(context)
return context
def __str__(self):
return str(self.delivery_key)
class DeliveryDetails(models.Model):
delivery = models.ForeignKey(Delivery, on_delete=models.CASCADE, related_name=_("delivery"))
distance = models.DecimalField(_("Distance Approximative "), max_digits=7, decimal_places=2)
delivery_price = models.DecimalField(max_digits=7, decimal_places=2)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True, editable=False)
updated_at = models.DateTimeField(_("Updated at"), auto_now=True)
def __str__(self):
return str(self.created_at)
***Views***
class DeliveryCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView, FormView):
model = Delivery
form_class = UserDeliveryForm
template_name = "deliveries/customer/edit_deliveries.html"
def get_success_url(self):
return reverse(
"delivery:delivery-details",
kwargs={"pk": self.object.pk, "distance": self.object.distance},
)
def test_func(self):
return self.request.user.is_active
class DetailsDeliveryCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView, FormView):
model = DeliveryDetails
form_class = DeliveryDetailsForm
template_name = "deliveries/responsable/edit_deliveries_details.html"
success_url = reverse_lazy("account:dashboard")
def test_func(self):
return self.request.user.is_active
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
delivery = Delivery.objects.filter(id=self.kwargs["pk"])
context["form"].fields["delivery"].queryset = delivery
distance = Delivery.objects.get(id=self.kwargs["pk"]).distance["google_distance"]
return context
有没有办法在 DetailleDelivery 中获取 Delivery 实例(发票键和距离)并在用户填写 DeliveryDetailsForm 时将它们显示给用户? 如果可能的话,我想避免多次访问数据库以获得相同的数据。
在您的 DetailsDeliveryCreateView
中设置表单初始值:
def get_initial(self):
initial = super(DetailsDeliveryCreateView, self).get_initial()
initial = initial.copy()
delivery = Delivery.objects.get(id=self.kwargs["pk"])
distance = delivery.distance["google_distance"]
initial['distance'] = delivery
initial['distance'] = distance
return initial
您可以将传递传递到上下文中,如下所示:
上下文 ['delivery'] = 交付
然后在您的模板中,您可以使用 {{delivery.distance}} 以及您需要的任何其他内容。您将拥有整个对象。
显然这仅适用于相关父对象尚不存在的创建视图。在详细视图中,您可以通过子项访问父项。
此外,您可能希望使用 get_object_or_404 而不是过滤器来获取您的 Delivery 实例,以防有人尝试不存在的 pk。
此外,如果有意义的话,不要在表格中插入您的交付,只需将其完全关闭并覆盖您的 form_valid() 以在保存之前插入交付关系。