You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django Admin中实现订单关联产品标题的自动显示

解决Django Admin查看订单产品标题及自动关联问题

一、在订单页面直接查看已订购产品标题

方法1:用Inline展示订单项(最便捷)

在admin.py中给Order的Admin配置添加Inline,这样查看单个订单详情时,无需切换页面就能直接看到所有关联的产品信息:

from django.contrib import admin
from .models import Order, OrderItem, Photograph

class OrderItemInline(admin.TabularInline):
    model = OrderItem
    extra = 0  # 不显示多余的空白添加行
    readonly_fields = ('product', 'quantity', 'unit_price', 'get_total')  # 无需修改的字段设为只读

class OrderAdmin(admin.ModelAdmin):
    list_display = ('id', 'customer', 'order_date', 'order_status', 'get_product_titles')
    inlines = [OrderItemInline]  # 订单详情页下方显示关联订单项

    # 自定义方法:拼接该订单下所有产品的标题
    def get_product_titles(self, obj):
        return ', '.join([item.product.title for item in obj.orderitem_set.all()])
    get_product_titles.short_description = '已订购产品'  # 列表页列名

admin.site.register(Order, OrderAdmin)
admin.site.register(OrderItem)
admin.site.register(Photograph)

设置完成后:

  • 订单列表页会新增「已订购产品」列,直接显示该订单下所有产品标题的逗号分隔列表
  • 点击单个订单进入详情页,下方会列出所有订单项,包含产品标题、数量、单价等信息

方法2:仅在订单列表页显示产品标题

如果只需要在列表页快速查看产品标题,无需详情页的Inline,仅保留上述的get_product_titles方法和list_display配置即可。

二、解决产品需手动选择的问题

你提到用ForeignKey后必须手动下拉选择产品,这是Django Admin的默认渲染逻辑。针对不同业务场景,解决方案如下:

场景1:用户下单时自动生成订单项

如果是前端用户下单后由后端自动创建订单和订单项,无需在Admin手动操作。后端示例代码如下(假设能获取用户选中的产品ID列表):

# 创建主订单
order = Order.objects.create(customer=目标客户实例, order_status='P')
# 循环创建对应订单项
for product_id in 用户选中的产品ID列表:
    product = Photograph.objects.get(id=product_id)
    OrderItem.objects.create(
        order=order,
        product=product,
        quantity=购买数量,
        unit_price=product.price  # 注意:Photograph模型需补充price字段才能使用
    )

场景2:Admin中创建订单时快速选择产品

如果需要在Admin创建订单时直接添加产品,将OrderItem的Inline改为可编辑状态即可:

class OrderItemInline(admin.TabularInline):
    model = OrderItem
    extra = 1  # 显示1个空白行用于添加新订单项
    fields = ('product', 'quantity', 'unit_price', 'get_total')

这样在Admin创建订单时,可直接在同一页面添加订单项、选择产品,无需单独创建OrderItem。

另外,你的OrderItem模型中__str__方法存在错误(self.order_id字段不存在),修改为以下内容后,Admin中查看OrderItem时也能直接看到产品标题:

class OrderItem(models.Model):
    # 其他字段保持不变
    def __str__(self):
        return f"{self.product.title} (订单ID: {self.order.id})"

内容的提问来源于stack exchange,提问作者David Henson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:35:41