如何在Django中编写基于类的视图实现自动创单及添加订单项
实现自动创建订单并添加订单项的Django类视图
先修正模型里的小问题
你的OrderRow模型__str__方法存在语法错误,直接拼接对象与整数会触发类型错误,建议修改为:
def __str__(self) -> str: return f"{self.product} {self.quantity} {self.unit}"
或者显式转换类型:
def __str__(self) -> str: return str(self.product) + " " + str(self.quantity) + " " + str(self.unit)
1. 编写订单项表单类
创建表单用于收集订单项信息,自动排除order字段(后续会在视图中关联到已创建的订单):
from django import forms from .models import OrderRow class OrderRowForm(forms.ModelForm): class Meta: model = OrderRow fields = ['product', 'quantity', 'unit']
2. 核心类视图实现
基于TemplateView结合登录验证,完成「进入页面自动创建订单」「提交表单添加订单项」的逻辑:
from django.views.generic import TemplateView from django.contrib.auth.mixins import LoginRequiredMixin from .models import Order, OrderRow from .forms import OrderRowForm class OrderCreateAndAddRowView(LoginRequiredMixin, TemplateView): template_name = 'orders/order_add_row.html' def get(self, request, *args, **kwargs): # 仅当session中无当前订单时创建新订单,避免刷新页面重复创建 if not request.session.get('current_order_id'): order = Order.objects.create(customer=request.user) request.session['current_order_id'] = order.id return super().get(request, *args, **kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 从session获取当前订单及对应订单项,传递到模板 order_id = self.request.session.get('current_order_id') if order_id: order = Order.objects.get(id=order_id) context['order'] = order context['order_rows'] = OrderRow.objects.filter(order=order) # 传递订单项表单到模板 context['form'] = OrderRowForm() return context def post(self, request, *args, **kwargs): form = OrderRowForm(request.POST) if form.is_valid(): order_id = request.session.get('current_order_id') if order_id: order = Order.objects.get(id=order_id) # 关联订单后保存订单项 order_row = form.save(commit=False) order_row.order = order order_row.save() # 提交后刷新页面,展示最新订单项 return self.get(request, *args, **kwargs)
3. 编写页面模板
创建templates/orders/order_add_row.html,展示订单信息、已有订单项和添加表单:
<h2>当前订单: {{ order }}</h2> <h3>已选商品</h3> <ul> {% for row in order_rows %} <li>{{ row }}</li> {% empty %} <li>还未添加任何商品</li> {% endfor %} </ul> <h3>添加新商品</h3> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">添加</button> </form>
4. 配置URL路由
在应用的urls.py中添加路由:
from django.urls import path from .views import OrderCreateAndAddRowView urlpatterns = [ path('order/new/', OrderCreateAndAddRowView.as_view(), name='create_order_with_rows'), ]
关键逻辑说明
LoginRequiredMixin确保只有登录用户能访问页面,符合订单关联用户的需求- 首次访问页面时自动创建订单,将订单ID存入session,后续操作都基于该订单
- 表单提交时自动关联到session中的订单,无需用户手动选择
- 刷新页面不会重复创建订单,而是继续使用当前会话中的订单
内容的提问来源于stack exchange,提问作者Hamed Mohammadi
相关产品推荐
相关产品推荐

