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

Django表单如何获取ForeignKey的name而非id?

解决Django中获取ForeignKey关联对象名称的问题

好问题!你遇到的情况是因为Django表单里的ForeignKey字段默认会渲染成下拉选择框,提交的是关联对象的ID值,而不是对象本身。要拿到对应的company.name,有两种更靠谱的方式,我帮你梳理下:

方法一:利用表单的cleaned_data(推荐)

表单在验证通过后,cleaned_data里会直接包含对应的Company对象,而不是ID。这种方式更安全,因为Django已经帮你验证了ID的有效性,不需要自己处理查询异常:

修改你的views.py中的form_valid方法:

class Employee(CreateView):
    fields = ('name','company')
    model = models.Employee

    def form_valid(self, form):
        self.object = form.save(commit=False)
        # 从cleaned_data中获取已验证的Company对象
        company_obj = form.cleaned_data.get('company')
        
        if company_obj:  # 处理company字段为null的情况
            comp_name = company_obj.name
            # 注意:你原代码里的变量名写错了,dept_name应该改为comp_name
            shop_id = ""
            for word in comp_name.split(" "):
                shop_id += word[:1]
            self.object.nik = shop_id[-3:]
        
        self.object.save()
        # 这里原代码的super参数错误,应该调用当前类的父类方法
        return super().form_valid(form)

方法二:通过POST获取的ID查询Company对象

如果你一定要用request.POST获取ID,那么需要手动查询对应的对象,但要注意处理ID无效的情况:

class Employee(CreateView):
    fields = ('name','company')
    model = models.Employee

    def form_valid(self, form):
        self.object = form.save(commit=False)
        comp_id = self.request.POST.get("company", "")
        
        if comp_id.isdigit():
            try:
                company_obj = models.Company.objects.get(id=comp_id)
                comp_name = company_obj.name
                shop_id = ""
                for word in comp_name.split(" "):
                    shop_id += word[:1]
                self.object.nik = shop_id[-3:]
            except models.Company.DoesNotExist:
                # 处理找不到对应公司的情况,比如设置默认值
                self.object.nik = ""
        else:
            self.object.nik = ""
        
        self.object.save()
        return super().form_valid(form)

额外提醒

你原代码里有两个小问题需要注意:

  • 变量名错误:dept_name应该改为comp_name,否则会抛出未定义的变量异常
  • super调用错误:原代码写的super(ModelFormMixin, self).form_valid(form)会跳过CreateView的逻辑,应该改为super().form_valid(form)或者super(Employee, self).form_valid(form)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:17:12