Django 在视图中将表单添加到表单集中
Django add forms to formset in a view
我遇到了设计问题。
想象一个订单模型和material模型,
class Material(models.Model):
material_code = models.CharField(max_length=40)
standard_price = models.DecimalField()
class Order(models.Model):
customer = models.ForeignKey(Customer)
class OrderItems(models.Model):
order = models.ForeignKey(Order)
material = models.ForeignKey(Material)
price = models.DecimalField()
在我的订单详细信息视图中,我使用 inlineformset_factory(Order, OrderItems)
填充订单项
我想要的行为如下:
如果用户想添加更多订单项,我想将用户重定向到 material 列表页面,用户选择一个或多个 material 并确认,然后我将他重定向到订单详细信息视图有新添加的项目。
我正在考虑这些工作,比如带有中间页面的 django 管理操作。
在向订单中添加新的 orderitems 之前,我还想从 material standard_price 设置 orderitems 价格,这意味着我想在将其添加到 orderitems 之前修改 formsets 值。
我想问的问题是,有没有更简单的方法来实现这一点,似乎将表单集数据存储到会话并用新项目重新填充表单集并不容易。我会考虑另一种解决这个问题的方法。
顺便说一句,我不想要 js 解决方案,想象一下我的订单模型上的一个字段,grandtotal,我可以计算项目总金额,使用 js 解决方案我可能必须用 js 做计算逻辑,用户添加一个项目并更改价格,然后我用 js 进行总计计算。这是我想避免的。
您可以通过 "Adding dynamic fields" 将其简化为您的订单详细信息表单。
当用户单击 "Add material" 按钮时,将向表单添加一个新字段(例如 <select>
包含材料列表的字段)。
此 link 将帮助您完成任务。
根据您提供的描述,我没有找到 formsets 的用例。
您只需要一个 material 目录页,其中列出了 material。每个 material 都可以添加到当前购物车,这是通过 Ajax 调用 url 来完成的,该 url 传递 material 的 PK,因此视图对于 Ajax 调用可以创建购物车并将 material 添加到购物车。
最后您需要一个 OrderDetail,您需要对当前在用户购物车中的所有 material 进行 forloop。
你可以先完全在数据库中实现,为Cart定义关系模型,其实就是你已经实现的Orderclass
然后你可以添加一个缓存层来限制 writes/deletes/updates 到数据库,使用 django 会话(考虑到你不在你的数据库中存储会话,这有一个性能提升!)
所以总而言之,您可能需要的是(我使用购物车的概念,暗示用户只能有一个有效订单,如果您的要求不同,它可以很容易地更改为您想要的提供了您的订单模型):
数据模型:
class Cart:
user = 1to1(User, related_name='cart') # Can be a FK if you want several active orders
is_approved = Boolean # To tell if the order is considered Over or is still open
created_at = DateTimeField
...
class Material:
orders = M2M(Cart, through=CartItem)
...
class CartItem:
cart = FK(Cart)
material = FK(Material)
...
观看次数:
def list_materials(request):
returns_rendered_template_with(materials=Material.objects.all())
#Ajax method, called via Post, you probably need a way to also delete, or edit (number of materials to order ?)
def add_material_to_cart(request, material_id):
cart = Cart.objects.get_or_create(user=request.user)
material = Material.objects.get(pk=material_id)
CartItem(material=material, cart=cart).save()
def order_detail_view(request):
cart = user.cart
cart_items = CartItems.objects.filter(cart=cart)
returns_rendered_template_with(cart_items=cart_items)
模板:
material_list.html
....
{% for item in materials %}
{% show material info, such as price, availability, ... %}
<button data-pk={{item.pk}}, ...> to call add_material_to_cart </button>
{% endfor %}
order_detail.html
....
{% for item in cart_items %}
{% show each cart_item.material and its information + whatever you need %}
{% endfor %}
这是你可以实现的最基本的形式,我明白了,你想要的。
您可以将这些视图中的几个合并在一起,您可以实现一个“完全在会话中”的解决方案,而不需要 Cart 和 CartItem 模型,只是最终订单被持久化到我不知道,比尔模型?订单历史 ?随心所欲
如果我理解你的意图是正确的,你想创建某种购物车,而不想为尚未下达的订单创建数据库条目。
我的建议是创建一个 Cart
模型和一个 CartItem
模型来存储有关购物车中当前有哪些商品的信息。
当客户下订单时,您使用购物车及其商品中相应的 OrderItem
实例创建一个新的 Order
实例,并保留该实例。
Cart
和 CartItem
可以是存储在数据库中的 Django 模型,也可以是普通的 Python 类 并将它们序列化以存储在会话中。
将它们存储在数据库中可能更容易,但很可能会生成比基于会话的解决方案更多的数据库查询。这是否是一个问题取决于您的服务器容量和预期负载。这种方法在 Oscar 中实现,这是一个 Django 的电子商务框架。
我遇到了设计问题。
想象一个订单模型和material模型,
class Material(models.Model):
material_code = models.CharField(max_length=40)
standard_price = models.DecimalField()
class Order(models.Model):
customer = models.ForeignKey(Customer)
class OrderItems(models.Model):
order = models.ForeignKey(Order)
material = models.ForeignKey(Material)
price = models.DecimalField()
在我的订单详细信息视图中,我使用 inlineformset_factory(Order, OrderItems)
填充订单项我想要的行为如下:
如果用户想添加更多订单项,我想将用户重定向到 material 列表页面,用户选择一个或多个 material 并确认,然后我将他重定向到订单详细信息视图有新添加的项目。
我正在考虑这些工作,比如带有中间页面的 django 管理操作。
在向订单中添加新的 orderitems 之前,我还想从 material standard_price 设置 orderitems 价格,这意味着我想在将其添加到 orderitems 之前修改 formsets 值。
我想问的问题是,有没有更简单的方法来实现这一点,似乎将表单集数据存储到会话并用新项目重新填充表单集并不容易。我会考虑另一种解决这个问题的方法。
顺便说一句,我不想要 js 解决方案,想象一下我的订单模型上的一个字段,grandtotal,我可以计算项目总金额,使用 js 解决方案我可能必须用 js 做计算逻辑,用户添加一个项目并更改价格,然后我用 js 进行总计计算。这是我想避免的。
您可以通过 "Adding dynamic fields" 将其简化为您的订单详细信息表单。
当用户单击 "Add material" 按钮时,将向表单添加一个新字段(例如 <select>
包含材料列表的字段)。
此 link 将帮助您完成任务。
根据您提供的描述,我没有找到 formsets 的用例。
您只需要一个 material 目录页,其中列出了 material。每个 material 都可以添加到当前购物车,这是通过 Ajax 调用 url 来完成的,该 url 传递 material 的 PK,因此视图对于 Ajax 调用可以创建购物车并将 material 添加到购物车。
最后您需要一个 OrderDetail,您需要对当前在用户购物车中的所有 material 进行 forloop。
你可以先完全在数据库中实现,为Cart定义关系模型,其实就是你已经实现的Orderclass
然后你可以添加一个缓存层来限制 writes/deletes/updates 到数据库,使用 django 会话(考虑到你不在你的数据库中存储会话,这有一个性能提升!)
所以总而言之,您可能需要的是(我使用购物车的概念,暗示用户只能有一个有效订单,如果您的要求不同,它可以很容易地更改为您想要的提供了您的订单模型):
数据模型:
class Cart:
user = 1to1(User, related_name='cart') # Can be a FK if you want several active orders
is_approved = Boolean # To tell if the order is considered Over or is still open
created_at = DateTimeField
...
class Material:
orders = M2M(Cart, through=CartItem)
...
class CartItem:
cart = FK(Cart)
material = FK(Material)
...
观看次数:
def list_materials(request):
returns_rendered_template_with(materials=Material.objects.all())
#Ajax method, called via Post, you probably need a way to also delete, or edit (number of materials to order ?)
def add_material_to_cart(request, material_id):
cart = Cart.objects.get_or_create(user=request.user)
material = Material.objects.get(pk=material_id)
CartItem(material=material, cart=cart).save()
def order_detail_view(request):
cart = user.cart
cart_items = CartItems.objects.filter(cart=cart)
returns_rendered_template_with(cart_items=cart_items)
模板:
material_list.html
....
{% for item in materials %}
{% show material info, such as price, availability, ... %}
<button data-pk={{item.pk}}, ...> to call add_material_to_cart </button>
{% endfor %}
order_detail.html
....
{% for item in cart_items %}
{% show each cart_item.material and its information + whatever you need %}
{% endfor %}
这是你可以实现的最基本的形式,我明白了,你想要的。
您可以将这些视图中的几个合并在一起,您可以实现一个“完全在会话中”的解决方案,而不需要 Cart 和 CartItem 模型,只是最终订单被持久化到我不知道,比尔模型?订单历史 ?随心所欲
如果我理解你的意图是正确的,你想创建某种购物车,而不想为尚未下达的订单创建数据库条目。
我的建议是创建一个 Cart
模型和一个 CartItem
模型来存储有关购物车中当前有哪些商品的信息。
当客户下订单时,您使用购物车及其商品中相应的 OrderItem
实例创建一个新的 Order
实例,并保留该实例。
Cart
和 CartItem
可以是存储在数据库中的 Django 模型,也可以是普通的 Python 类 并将它们序列化以存储在会话中。
将它们存储在数据库中可能更容易,但很可能会生成比基于会话的解决方案更多的数据库查询。这是否是一个问题取决于您的服务器容量和预期负载。这种方法在 Oscar 中实现,这是一个 Django 的电子商务框架。