将模型 属性 值发送到其他模型并以其形式显示

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() 以在保存之前插入交付关系。