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

Django Admin内联创建视图如何过滤数据?仅展示当前客户产品

解决Django Admin内联下拉仅显示当前客户产品的问题

方法一:自定义内联表单实现动态过滤

假设你的模型结构大致如下(可根据实际情况调整字段名):

# models.py
from django.db import models

class Client(models.Model):
    name = models.CharField(max_length=100)
    # 其他业务字段

class Product(models.Model):
    name = models.CharField(max_length=100)
    client = models.ForeignKey(Client, on_delete=models.CASCADE, related_name="products")
    # 其他业务字段

class ContractProduct(models.Model):
    client = models.ForeignKey(Client, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    # 其他业务字段

首先定义一个自定义表单,在初始化时根据当前关联的客户过滤产品选项:

# admin.py
from django import forms
from .models import ContractProduct, Product

class ContractProductInlineForm(forms.ModelForm):
    class Meta:
        model = ContractProduct
        fields = "__all__"

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 获取当前内联关联的客户实例
        current_client = self.instance.client
        if current_client:
            self.fields["product"].queryset = Product.objects.filter(client=current_client)

接着在自定义的内联类中使用这个表单,并通过get_formset确保新增空白表单时也能拿到父客户对象:

from django.contrib import admin
from .models import Client, ContractProduct

class ContractProductInline(admin.TabularInline):
    model = ContractProduct
    form = ContractProductInlineForm
    extra = 1

    def get_formset(self, request, obj=None, **kwargs):
        formset = super().get_formset(request, obj, **kwargs)
        # 给新增的空白表单设置产品过滤条件
        if obj:
            formset.form.base_fields["product"].queryset = Product.objects.filter(client=obj)
        return formset

@admin.register(Client)
class ClientAdmin(admin.ModelAdmin):
    inlines = [ContractProductInline]

方法二:直接在內联类中重写字段过滤方法

如果不想单独写表单类,也可以直接在内联类里重写formfield_for_foreignkey和get_formset:

class ContractProductInline(admin.TabularInline):
    model = ContractProduct
    extra = 1

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        field = super().formfield_for_foreignkey(db_field, request, **kwargs)
        # 仅对product字段应用过滤,且确保已获取到父客户对象
        if db_field.name == "product" and hasattr(self, "parent_client"):
            field.queryset = field.queryset.filter(client=self.parent_client)
        return field

    def get_formset(self, request, obj=None, **kwargs):
        # 把当前客户对象保存到內联实例中,供字段过滤使用
        self.parent_client = obj
        return super().get_formset(request, obj, **kwargs)

关键注意点

  • 确认Product模型和Client的外键关联字段名与代码一致(比如代码中用client,如果你的模型是customer要对应修改)
  • 如果当前客户没有关联产品,下拉列表会是空的,属于正常情况
  • 两种方法都能覆盖编辑已有内联对象、新增空白内联对象的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:25:32