我遇到了设计问题。
想象一下订单模型和材料模型,
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)填充订单项
我想要的行为如下:
如果用户想要添加更多订购项目,我想将用户重定向到材料列表页面,用户选择一种或多种材料并确认,然后我将其重定向到新添加项目的订单详细信息视图。
我正在考虑这些工作,例如django管理中心页面的操作。
在添加订购新订单之前,我还想从物料standard_price设置订购项价格,这意味着我想在将其添加到订单项之前修改formsets值。
我想问的问题是,是否有一种更简单的方法来实现这一点,似乎将formset数据存储到会话并使用新项目重新填充formset并不容易。我会考虑解决这个问题的另一种方法。
我不想要js解决方案,想象一下我的订单模型上的字段,grandtotal,我可以计算总项目数量,用js解决方案我可能需要用js做计算逻辑,用户添加项目并更改价格然后我用js进行大计算。这是我想要避免的。
答案 0 :(得分:5)
根据您提供的说明,我找不到 formsets 的用例。
您只需要一个列出材料的材料目录页面。每种材料都可以添加到当前购物车中,这是通过Ajax调用传递到材料PK的URL来完成的,因此该Ajax调用的视图可以创建购物车并将该材料添加到购物车。
最后你需要一个OrderDetail,你需要一个关于所有材料的forloop,目前在用户购物车中。
您可以先在数据库中完全实现它,并为Cart定义关系模型,这实际上是您已经实施的Order类。
然后你可以添加一个缓存层来限制对DB的写入/删除/更新,使用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 %}
这是你能实现的最基本的形式,我明白,你想要的 您可以将多个这些视图合并在一起,您可以在会话中实现&#34; &#34;解决方案,不需要Cart和CartItem模型,只是最终确定的订单持续存在,我不知道,Bill模型?订单历史 ?无论你想要什么。
答案 1 :(得分:1)
如果我理解你的意图,你想创建某种购物车,而你不想为尚未放置的订单创建数据库条目。
我的建议是创建一个Cart
模型和一个CartItem
模型,用于存储有关购物车中当前商品的信息。
当客户下订单时,您可以使用购物车及其商品中相应的Order
个实例创建新的OrderItem
实例,并保留该实例。
Cart
和CartItem
可以是存储在数据库中的Django模型,也可以是普通的Python类,并将它们序列化以便在会话中存储。
将它们存储在数据库中可能更容易,但很可能比基于会话的解决方案生成更多数据库查询。这是否是一个问题取决于您的服务器容量和预期负载。这种方法在Oscar实现,这是Django的电子商务框架。
答案 2 :(得分:0)
您可以通过“添加动态字段”将其简化为订单明细窗体。
当用户点击“添加素材”按钮时,系统会添加一个新字段(例如带有素材列表的program tailrec
use iso_fortran_env
implicit none
integer(int64) :: acc, x
acc = 0
x = 500000000
call tailrecsum(x, acc)
print *, acc
contains
recursive subroutine tailrecsum (x, running_total)
integer(int64), intent(inout) :: x
integer(int64), intent(inout) :: running_total
integer(int64) :: ret_val
if (x == 0) return
running_total = running_total + x
x = x - 1
call tailrecsum (x, running_total)
end subroutine tailrecsum
end program
字段)。
这link将帮助您完成任务。