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

如何在Django中实现ForeignKey关联查询并生成下拉选项

Django实现指定查询并自定义下拉选项显示

一、实现对应SQL的Django查询

原SQL通过内连接关联locations和regions,筛选出有对应区域的地点并按名称排序,在Django中可以这样实现:

# 获取符合条件的查询集
location_queryset = Locations.objects.select_related('region') \
                                     .filter(region__isnull=False) \
                                     .order_by('name')
  • select_related('region'):执行SQL内连接,一次性拉取关联的区域数据,避免N+1查询问题,对应原SQL的inner join逻辑
  • filter(region__isnull=False):明确筛选出绑定了区域的地点,和内连接效果一致
  • order_by('name'):按地点名称排序,对应原SQL的order by locations.name

二、实现下拉框显示「地点名称-区域名称」格式

有两种常用方案,可根据需求选择:

方案1:重写模型的__str__方法(全局生效,推荐)

修改Locations模型,重写__str__方法直接返回拼接后的格式,这样所有使用该模型的下拉框都会自动显示指定样式:

class Locations(models.Model):
    region = models.ForeignKey(Regions, on_delete=models.CASCADE, blank=True, null=True)
    name = models.CharField(max_length=255)

    def __str__(self):
        # 存在关联区域时拼接,否则仅返回地点名称
        if self.region:
            return f"{self.name}-{self.region.region_name}"
        return self.name

之后在表单中直接使用查询集即可:

from django import forms

class LocationSelectForm(forms.Form):
    location = forms.ModelChoiceField(
        queryset=location_queryset,
        label="选择地点"
    )

方案2:在表单中自定义显示逻辑(局部生效)

如果不想修改模型的__str__方法,可在表单的ModelChoiceField中通过label_from_instance参数自定义选项文本:

from django import forms

class LocationSelectForm(forms.Form):
    location = forms.ModelChoiceField(
        queryset=location_queryset,
        label="选择地点",
        # 自定义每个选项的显示内容
        label_from_instance=lambda obj: f"{obj.name}-{obj.region.region_name}"
    )

也可以提前在查询时拼接好显示字段,再在表单中调用:

from django.db.models import Value, CharField
from django.db.models.functions import Concat

# 提前拼接显示字段
location_queryset = Locations.objects.select_related('region') \
                                     .filter(region__isnull=False) \
                                     .annotate(
                                         display_name=Concat(
                                             'name', Value('-'), 'region__region_name',
                                             output_field=CharField()
                                         )
                                     ) \
                                     .order_by('name')

# 表单中使用
class LocationSelectForm(forms.Form):
    location = forms.ModelChoiceField(
        queryset=location_queryset,
        label="选择地点",
        label_from_instance=lambda obj: obj.display_name
    )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 10:55:25