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

在Django表单CharField中实现数据库驱动的自动补全功能

实现Django表单字段的自动补全建议

方法一:使用django-autocomplete-light(快速集成)

  1. 安装依赖
pip install django-autocomplete-light
  1. 在settings.py中添加应用
INSTALLED_APPS = [
    # ... 其他已存在的应用
    'dal',
    'dal_select2',
    'django.contrib.staticfiles',  # 确保已添加
]
  1. 创建自动补全视图
    在对应app的views.py中添加:
from dal import autocomplete
from .models import Album

class ArtistAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        # 获取去重的艺术家列表,支持模糊搜索
        qs = Album.objects.values_list('artist', flat=True).distinct()
        qs = Album.objects.filter(artist__in=qs)
        if self.q:
            qs = qs.filter(artist__icontains=self.q)
        return qs.values_list('artist', flat=True).distinct()

class AlbumAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        qs = Album.objects.values_list('album', flat=True).distinct()
        qs = Album.objects.filter(album__in=qs)
        if self.q:
            qs = qs.filter(album__icontains=self.q)
        return qs.values_list('album', flat=True).distinct()
  1. 配置路由
    在项目urls.py中添加:
from django.urls import path
from .views import ArtistAutocomplete, AlbumAutocomplete

urlpatterns = [
    # ... 其他路由
    path('artist-autocomplete/', ArtistAutocomplete.as_view(), name='artist-autocomplete'),
    path('album-autocomplete/', AlbumAutocomplete.as_view(), name='album-autocomplete'),
]
  1. 修改表单类
    替换原有的CharField为自动补全字段:
from dal import autocomplete
from django import forms

class MakeGuessForm(forms.Form):
    artist = autocomplete.Select2ListCreateChoiceField(
        choice_list=lambda: Album.objects.values_list('artist', flat=True).distinct(),
        widget=autocomplete.ListSelect2(url='artist-autocomplete')
    )
    album = autocomplete.Select2ListCreateChoiceField(
        choice_list=lambda: Album.objects.values_list('album', flat=True).distinct(),
        widget=autocomplete.ListSelect2(url='album-autocomplete')
    )
  1. 模板中渲染表单
    加载静态资源并渲染表单:
{% load static %}
<link rel="stylesheet" href="{% static 'select2/dist/css/select2.min.css' %}">
<script src="{% static 'jquery/dist/jquery.min.js' %}"></script>
<script src="{% static 'select2/dist/js/select2.min.js' %}"></script>
<script src="{% static 'dal/js/select2.js' %}"></script>

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">提交</button>
</form>

方法二:自定义AJAX + Select2(无第三方依赖,灵活可控)

如果不想引入额外库,可手动实现:

  1. 准备静态资源
    下载Select2静态文件包,解压后将css和js文件放入项目static目录,模板中引入:
{% load static %}
<link rel="stylesheet" href="{% static 'select2/css/select2.min.css' %}">
<script src="{% static 'jquery/jquery.min.js' %}"></script>
<script src="{% static 'select2/js/select2.min.js' %}"></script>
  1. 创建AJAX接口视图
    在views.py中添加:
from django.http import JsonResponse
from .models import Album

def get_artists(request):
    query = request.GET.get('q', '')
    artists = Album.objects.filter(artist__icontains=query).values_list('artist', flat=True).distinct()
    return JsonResponse(list(artists), safe=False)

def get_albums(request):
    query = request.GET.get('q', '')
    albums = Album.objects.filter(album__icontains=query).values_list('album', flat=True).distinct()
    return JsonResponse(list(albums), safe=False)
  1. 配置路由
urlpatterns = [
    # ... 其他路由
    path('api/artists/', get_artists, name='api-artists'),
    path('api/albums/', get_albums, name='api-albums'),
]
  1. 定义表单类
    使用普通CharField即可:
from django import forms

class MakeGuessForm(forms.Form):
    artist = forms.CharField(label='艺术家', required=True)
    album = forms.CharField(label='专辑', required=True)
  1. 模板中初始化自动补全
<form method="post">
    {% csrf_token %}
    <div class="form-group">
        {{ form.artist.label_tag }}
        {{ form.artist }}
    </div>
    <div class="form-group">
        {{ form.album.label_tag }}
        {{ form.album }}
    </div>
    <button type="submit">提交</button>
</form>

<script>
$(document).ready(function() {
    $('#id_artist').select2({
        ajax: {
            url: "{% url 'api-artists' %}",
            dataType: 'json',
            delay: 250,
            data: function(params) {
                return { q: params.term };
            },
            processResults: function(data) {
                return {
                    results: $.map(data, function(item) {
                        return { text: item, id: item };
                    })
                };
            },
            cache: true
        },
        minimumInputLength: 1,
        placeholder: '输入艺术家名称'
    });

    $('#id_album').select2({
        ajax: {
            url: "{% url 'api-albums' %}",
            dataType: 'json',
            delay: 250,
            data: function(params) {
                return { q: params.term };
            },
            processResults: function(data) {
                return {
                    results: $.map(data, function(item) {
                        return { text: item, id: item };
                    })
                };
            },
            cache: true
        },
        minimumInputLength: 1,
        placeholder: '输入专辑名称'
    });
});
</script>

注意事项

  • 两种方案都通过.distinct()确保选项无重复
  • 生产环境建议将静态文件本地化,避免依赖外部资源
  • 自定义AJAX方案可根据需求调整触发补全的最小输入长度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 08:25:35