python - 更改 Django autocomplete_fields 标签

标签 python django django-2.1

我正在尝试为 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 .

ModelAdmin您指定的类 autocomplete_fields , 导入您的 CustomDisplayAutocompleteSelect并添加以下方法:

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_viewModelAdmin自动完成正在显示结果的类(不是您指定 autocomplete_fields 的 ModelAdmin 类):
def autocomplete_view(self, request):
    return CustomAutocompleteJsonView.as_view(model_admin=self)(request)

因此,如果您有 ModelAdmin类叫 YourModelAdminautocomplete_fields = ['something'] ,您将设置 autocomplete_view对应的ModelAdmin您的类(class) Something模型。

关于python - 更改 Django autocomplete_fields 标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55629887/

相关文章:

python - 什么是 Perl 等同于 Python 的 type() 函数

javascript - 将 Django 表列格式化为货币和 % 格式

django - Docker Compose ENTRYPOINT 和 CMD 与 Django 迁移

django - 如何让 Django 根据 HTTP 请求中的 "Host" header 确定要使用哪个 Site 对象?

python - 在 url 中组合多个 slug

python - 在 Python 中求多项式的导数

python - 在 NumPy 中旋转晶体

python - 写入多个 HDF5 文件时 Windows 中打开的文件过多

python - “WSGIRequest”对象没有属性 'is_authenticated'

django - 通过迁移将索引添加到Django中的模型字段