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

如何在Django中跨多模型关联实现订单按销售代理过滤?

解决Django多模型关联下按代理姓名过滤订单的问题

首先得明确你模型间的关联逻辑,假设你的模型大致是这样的(如果和实际有出入,调整关联字段即可):

from django.db import models

class Agent(models.Model):
    name = models.CharField(max_length=100)
    # 其他代理字段

class Customer(models.Model):
    name = models.CharField(max_length=100)
    # 其他客户字段

class Assignment(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    agent = models.ForeignKey(Agent, on_delete=models.CASCADE)
    year = models.IntegerField()  # 记录代理关联的年份

class Order(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    order_date = models.DateField()
    # 其他订单字段

    @property
    def agent_name(self):
        # 你当前获取代理姓名的属性
        year = self.order_date.year
        assignment = Assignment.objects.filter(customer=self.customer, year=year).first()
        return assignment.agent.name if assignment else ""

因为agent_name是模型的属性而非数据库字段,所以不能直接用它过滤。要实现按代理姓名过滤订单,得利用Django的跨模型关联查询(双下划线__语法),通过订单关联的客户、对应年份的分配记录,最终关联到代理的姓名字段。

具体实现方法

1. 精确匹配代理姓名

如果要筛选某代理负责的所有订单,需要同时匹配订单年份和分配记录的年份,确保是当年的代理:

from django.db.models import F

# 假设要筛选姓名为"张三"的代理的订单
target_agent_name = "张三"

orders = Order.objects.filter(
    # 关联到客户的Assignment记录
    customer__assignment__agent__name=target_agent_name,
    # 确保订单年份和Assignment的年份一致
    customer__assignment__year=F('order_date__year')
).distinct()  # 去重,避免同一个订单因关联多条Assignment被重复查询

2. 模糊匹配代理姓名(比如包含关键词)

用__contains或__icontains(不区分大小写):

orders = Order.objects.filter(
    customer__assignment__agent__name__icontains="张",
    customer__assignment__year=F('order_date__year')
).distinct()

3. 优化查询(避免N+1问题)

如果需要同时获取订单和代理信息,可以用select_related或prefetch_related提前加载关联数据:

orders = Order.objects.filter(
    customer__assignment__agent__name__icontains="张",
    customer__assignment__year=F('order_date__year')
).select_related('customer').prefetch_related(
    'customer__assignment__agent'
).distinct()

关键说明

  • 双下划线__用于跨模型关联查询,格式为关联字段__关联模型的字段,多层关联就一直往后加。
  • F('order_date__year')是Django的F表达式,用于引用当前模型的字段值,确保订单年份和分配记录的年份匹配,避免拿到客户其他年份的代理订单。
  • 加distinct()是因为一个客户可能有多个年份的Assignment记录,关联查询时可能会返回重复的订单,去重后得到正确结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:05:55