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

如何在Django表单中获取当前Record模型ID以过滤BDC查询集?

问题描述

在实现查询集过滤时遇到困难,无法获取表单对应的当前Record模型ID,具体是在forms.py的AddRecordForm中,需要根据当前Record的ID匹配BDC模型的ref字段,从而填充多选组件的选项:

queryset=BDC.objects.filter(ref = ???当前Record模型的ID??? ).values_list('model')

现有代码

views.py

def update_record(request, pk):
    if request.user.is_authenticated:
        current_record = Record.objects.get(id=pk)
        form = AddRecordForm(request.POST or None, instance=current_record)
        if form.is_valid():
            form.save()
            messages.success(request, "Record Has Been Updated!")
            return redirect('home')
        return render(request, 'update_record.html', {'form':form})
    else:
        messages.success(request, "You Must Be Logged In...")
        return redirect('home')

forms.py

class AddRecordForm(forms.ModelForm):
    testrever = forms.ModelMultipleChoiceField(widget=forms.widgets.SelectMultiple, queryset=BDC.objects.filter(ref = ???当前Record模型的ID???).values_list('model'))

    class Meta:
        model = Record
        exclude = ("user",)


class BDCform(forms.ModelForm):
    ref = forms.CharField(required=False, widget=forms.widgets.TextInput(attrs={"placeholder":"First Name", "class":"form-control"}), label="")
    model = forms.CharField(required=False, widget=forms.widgets.TextInput(attrs={"placeholder":"Last Name", "class":"form-control"}), label="")

    class Meta:
        model = BDC
        exclude = ("user",)

models.py

class Record(models.Model):
    id = models.CharField(primary_key=True, max_length=50)
    testrever = models.JSONField(max_length=500) 

    def __str__(self):
        return (f"{self.first_name} {self.last_name}")

class BDC(models.Model):
    ref = models.CharField(max_length=50)
    model = models.CharField(max_length=50)
解决方案

表单定义阶段无法直接获取当前Record实例的ID,需通过动态修改字段查询集实现需求,步骤如下:

  1. 修改AddRecordForm的初始化方法
    将testrever字段初始查询集设为空,在__init__方法中根据传入的Record ID或实例动态过滤BDC数据:
class AddRecordForm(forms.ModelForm):
    testrever = forms.ModelMultipleChoiceField(
        widget=forms.widgets.SelectMultiple,
        queryset=BDC.objects.none()  # 初始为空查询集
    )

    class Meta:
        model = Record
        exclude = ("user",)

    def __init__(self, *args, **kwargs):
        # 取出传入的record_id参数,若无则从instance中获取
        record_id = kwargs.pop('record_id', None)
        super().__init__(*args, **kwargs)
        
        # 优先使用表单关联的Record实例ID
        if self.instance and self.instance.pk:
            record_id = self.instance.pk
        
        # 根据Record ID过滤BDC,生成多选组件的选项
        if record_id:
            # 使用flat=True确保返回扁平的字符串列表,适配ModelMultipleChoiceField要求
            self.fields['testrever'].queryset = BDC.objects.filter(ref=record_id).values_list('model', flat=True)
    
    def clean_testrever(self):
        # 将多选结果转为列表,适配Record模型的JSONField类型
        return list(self.cleaned_data['testrever'])
  1. 更新视图中的表单初始化逻辑
    在update_record视图中初始化表单时,传入当前Record的ID(或直接依赖instance):
def update_record(request, pk):
    if request.user.is_authenticated:
        current_record = Record.objects.get(id=pk)
        # 传入record_id参数,或仅传instance即可(表单会自动读取instance.pk)
        form = AddRecordForm(request.POST or None, instance=current_record, record_id=pk)
        if form.is_valid():
            form.save()
            messages.success(request, "Record Has Been Updated!")
            return redirect('home')
        return render(request, 'update_record.html', {'form':form})
    else:
        messages.success(request, "You Must Be Logged In...")
        return redirect('home')

关键说明

  • ModelMultipleChoiceField要求查询集返回可迭代的单个值或模型实例,因此使用values_list('model', flat=True)生成扁平的字符串列表;
  • 新增clean_testrever方法将多选结果转为列表,确保能正确存入Record模型的JSONField字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 16:40:30