更改 Django autocomplete_fields 标签

2023-11-27

我正在尝试为以下类型的所有项目设置自定义标签autocomplete_fields.

到目前为止,对于下拉列表,人们会使用

...
class CustomDisplay(forms.ModelChoiceField):
    def label_from_instance(self, obj):
        return "Some custom text: {}".format(obj.name)
...
somethings = CustomDisplay(queryset=Something.object.all())
...

但使用这个autocomplete_fields = (somethings,)将导致自动完成取消并显示带有自定义文本的下拉菜单。


字段显示正常的原因select小部件的特点是,当您定义自定义字段时,您不会将小部件设置为AutocompleteSelect.

In the ModelAdmin您指定的类autocomplete_fields,导入你的CustomDisplay and AutocompleteSelect并添加以下方法:

from django.contrib.admin.widgets import AutocompleteSelect


class YourModelAdmin(admin.ModelAdmin):
    autocomplete_fields = ['something']

    ...

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        db = kwargs.get('using')

        if db_field.name == 'something':
            return CustomDisplay(queryset=Something.object.all(), widget=AutocompleteSelect(db_field.remote_field, self.admin_site, using=db))
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

这只会在您查看现有实例时显示自定义文本。当您查看自动完成下拉列表并选择一个条目时,不会生成标签label_from_instance(),但是从简单的str()里面打电话AutocompleteJsonView.

因此,假设您只想更改自动完成小部件中的标签(要全面更改标签,您显然只需更改模型__str()__方法),您还需要在中创建一个自定义类admin.py这修改了get()中的方法AutocompleteJsonView:

from django.contrib.admin.options import AutocompleteJsonView
from django.http import Http404, JsonResponse


class CustomAutocompleteJsonView(AutocompleteJsonView):
    def get(self, request, *args, **kwargs):
        if not self.model_admin.get_search_fields(request):
            raise Http404(
                '%s must have search_fields for the autocomplete_view.' %
                type(self.model_admin).__name__
            )
        if not self.has_perm(request):
            return JsonResponse({'error': '403 Forbidden'}, status=403)

        self.term = request.GET.get('term', '')
        self.paginator_class = self.model_admin.paginator
        self.object_list = self.get_queryset()
        context = self.get_context_data()

        # Replace this with the code below.
        #
        # return JsonResponse({
        #     'results': [
        #         {'id': str(obj.pk), 'text': str(obj)}
        #         for obj in context['object_list']
        #     ],
        #     'pagination': {'more': context['page_obj'].has_next()},
        # })

        return JsonResponse({
            'results': [
                {'id': str(obj.pk), 'text': 'Some custom text: {}'.format(obj.name)}
                for obj in context['object_list']
            ],
            'pagination': {'more': context['page_obj'].has_next()},
    })

现在设置autocomplete_view on the ModelAdmin自动完成功能正在显示结果的类(不是ModelAdmin您指定 autocomplete_fields 的类):

def autocomplete_view(self, request):
    return CustomAutocompleteJsonView.as_view(model_admin=self)(request)

所以如果你有一个ModelAdmin类称为YourModelAdmin with autocomplete_fields = ['something'],你会设置autocomplete_view对于相应的ModelAdmin为你的班级Something model.

Django 4.2 更新:

from django.contrib.admin.sites import AdminSite
from django.contrib.admin.widgets import AutocompleteSelect
from django.contrib.admin.views.autocomplete import AutocompleteJsonView
from django.core.exceptions import PermissionDenied


class CustomAdminSite(AdminSite):
    # This will change the view for all autocompletes.
    # You can handle specific cases within the autocomplete get() method.
    def autocomplete_view(self, request):
        return CustomAutocompleteJsonView.as_view(admin_site=self)(request)


admin_site = CustomAdminSite()


class CustomAutocompleteJsonView(AutocompleteJsonView):
    def get(self, request, *args, **kwargs):
        (
            self.term,
            self.model_admin,
            self.source_field,
            to_field_name,
        ) = self.process_request(request)

        if not self.has_perm(request):
            raise PermissionDenied

        self.object_list = self.get_queryset()
        context = self.get_context_data()
        if type(self.model_admin) == SomethingModelAdmin:
            return JsonResponse(
                {
                    "results": [
                        {'id': str(obj.pk), 'text': 'Some custom text: {}'.format(obj.name)}
                        for obj in context['object_list']
                    ],
                    "pagination": {"more": context["page_obj"].has_next()},
                }
            )
        else:
            return super().get(request, *args, **kwargs)


class YourModelAdmin(admin.ModelAdmin):
    autocomplete_fields = ['something']

    ...

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        db = kwargs.get('using')

        if db_field.name == 'something':
            return CustomDisplay(queryset=Something.objects.all(),
                                           widget=AutocompleteSelect(db_field,
                                                                     self.admin_site,
                                                                     using=db))
        return super().formfield_for_foreignkey(db_field, request, **kwargs)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更改 Django autocomplete_fields 标签 的相关文章

  • 如何在 Matplotlib 饼图周围绘制箭头以将每个标签指向圆圈中各自的部分?

    我一直在用 Matplotlib 绘制一些图表 我有一个饼图 想要在图表周围绘制箭头 使每个标签都指向图表 我有一个例子 这是我当前的代码 import matplotlib pyplot as plt plt rcParams font
  • 如何在 __init__ 中使用await设置类属性

    我如何定义一个类await在构造函数或类体中 例如我想要的 import asyncio some code class Foo object async def init self settings self settings setti
  • 为什么 dataclasses.astuple 返回类属性的深层副本?

    在下面的代码中astuple函数正在执行数据类的类属性的深层复制 为什么它不能产生与函数相同的结果my tuple import copy import dataclasses dataclasses dataclass class Dem
  • VSCode Settings.json 丢失

    我正在遵循教程 并尝试将 vscode 指向我为 Scrapy 设置的虚拟工作区 但是当我在 VSCode 中打开设置时 工作区设置 选项卡不在 用户设置 选项卡旁边 我还尝试通过以下方式手动转到文件 APPDATA Code User s
  • 我应该使用 Python 双端队列还是列表作为堆栈? [复制]

    这个问题在这里已经有答案了 我想要一个可以用作堆栈的 Python 对象 使用双端队列还是列表更好 元素数量较少还是数量较多有什么区别 您的情况可能会根据您的应用程序和具体用例而有所不同 但在一般情况下 列表非常适合堆栈 append is
  • 从Django中具有外键关系的两个表中检索数据? [复制]

    这个问题在这里已经有答案了 This is my models py file from django db import models class Author models Model first name models CharFie
  • GUI(输入和输出矩阵)?

    我需要创建一个 GUI 将数据输入到矩阵或表格中并读取此表单数据 完美的解决方案是限制输入表单仅允许float 例如 A 1 02 0 25 0 30 0 515 0 41 1 13 0 15 1 555 0 25 0 14 1 21 2
  • Python 内置的 super() 是否违反了 DRY?

    显然这是有原因的 但我没有足够的经验来认识到这一点 这是Python中给出的例子docs http docs python org 2 library functions html super class C B def method se
  • 如何将特定范围内的标量添加到 numpy 数组?

    有没有一种更简单 更节省内存的方法可以单独在 numpy 中执行以下操作 import numpy as np ar np array a l r ar c a a 0 l ar tolist a r 它可能看起来很原始 但它涉及获取给定数
  • Python 3:将字符串转换为变量[重复]

    这个问题在这里已经有答案了 我正在从 txt 文件读取文本 并且需要使用我读取的数据之一作为类实例的变量 class Sports def init self players 0 location name self players pla
  • 使用 python/numpy 重塑数组

    我想重塑以下数组 gt gt gt test array 11 12 13 14 21 22 23 24 31 32 33 34 41 42 43 44 为了得到 gt gt gt test2 array 11 12 21 22 13 14
  • 嵌套作用域和 Lambda

    def funct x 4 action lambda n x n return action x funct print x 2 prints 16 我不太明白为什么2会自动分配给n n是返回的匿名函数的参数funct 完全等价的定义fu
  • python的shutil.move()在linux上是原子的吗?

    我想知道python的shutil move在linux上是否是原子的 如果源文件和目标文件位于两个不同的分区上 行为是否不同 或者与它们存在于同一分区上时的行为相同吗 我更关心的是如果源文件和目标文件位于同一分区上 shutil move
  • Django 视图中的“请求”是什么

    在 Django 第一个应用程序的 Django 教程中 我们有 from django http import HttpResponse def index request return HttpResponse Hello world
  • Python - 如何确定解析的 XML 元素的层次结构级别?

    我正在尝试使用 Python 解析 XML 文件中具有特定标记的元素并生成输出 excel 文档 该文档将包含元素并保留其层次结构 我的问题是我无法弄清楚每个元素 解析器在其上迭代 的嵌套深度 XML 示例摘录 3 个元素 它们可以任意嵌套
  • 如何使用 Python 3 检查目录是否包含文件

    我到处寻找这个答案但找不到 我正在尝试编写一个脚本来搜索特定的子文件夹 然后检查它是否包含任何文件 如果包含 则写出该文件夹的路径 我已经弄清楚了子文件夹搜索部分 但检查文件却难倒了我 我发现了有关如何检查文件夹是否为空的多个建议 并且我尝
  • 找到一个数字所属的一组范围

    我有一个 200k 行的数字范围列表 例如开始位置 停止位置 该列表包括除了非重叠的重叠之外的所有类型的重叠 列表看起来像这样 3 5 10 30 15 25 5 15 25 35 我需要找到给定数字所属的范围 并对 100k 个数字重复该
  • 在 Google App Engine 中,如何避免创建具有相同属性的重复实体?

    我正在尝试添加一个事务 以避免创建具有相同属性的两个实体 在我的应用程序中 每次看到新的 Google 用户登录时 我都会创建一个新的播放器 当新的 Google 用户在几毫秒内进行多个 json 调用时 我当前的实现偶尔会创建重复的播放器
  • django 迁移地狱,丢了一张表。试图把它找回来

    所以我在数据库中删除了一个表 并且希望将其恢复 重新运行迁移会出现错误表不存在 经过一番搜寻后 我了解到我可以删除 django migrations 中应用程序名为我的应用程序的所有内容 所以我这样做了 重新运行迁移 它开始工作 然后抱怨
  • 如何使用 Boto3 启动具有 IAM 角色的 EC2 实例?

    我无法弄清楚如何使用指定的 IAM 角色在 Boto3 中启动 EC2 实例 以下是迄今为止我如何成功创建实例的一些示例代码 import boto3 ec2 boto3 resource ec2 region name us west 2

随机推荐