更改Django autocomplete_fields标签 [英] Change Django autocomplete_fields label

查看:57
本文介绍了更改Django autocomplete_fields标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to set a custom label for all of the items of a type in autocomplete_fields.

直到现在,对于下拉列表,将使用

Until now, for a drop-down list, one would use

...
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 =(某些东西)一起使用将导致自动完成取消,并显示带有自定义文本的下拉列表.

but using this with autocomplete_fields = (somethings,) will result in autocomplete canceling and showing me a dropdown with the custom text.

推荐答案

该字段显示常规 select 小部件的原因是,当您定义自定义字段时,无需设置该小部件作为 AutocompleteSelect .

The reason the field shows a normal select widget is that, when you define your custom field, you don't set the widget as an AutocompleteSelect.

在您指定 autocomplete_fields ModelAdmin 类中,导入您的 CustomDisplay AutocompleteSelect 并添加以下内容方法:

In the ModelAdmin class where you specify your autocomplete_fields, import your CustomDisplay and AutocompleteSelect and add the following method:

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()生成的,而是从 AutocompleteJsonView内部简单的 str()调用生成的.

That will only display the custom text when you view an existing instance. When you view the autocomplete drop down, and select an entry, the label is not generated from label_from_instance(), but from a straightforward str() call inside AutocompleteJsonView.

因此,假设您只想更改自动完成窗口小部件中的标签(要全面更改标签,您显然只需更改模型 __ str()__ 方法),则还需要创建 admin.py 中的自定义类,用于修改 AutocompleteJsonView 中的 get()方法:

So assuming you only want to change the label in the autocomplete widget (to change the label across the board you would obviously just change the model __str()__ method), you also need to create a custom class in admin.py that modifies the get() method in 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()},
    })

现在在要自动显示结果的 ModelAdmin 类上设置 autocomplete_view (不是您指定autocomplete_fields的 ModelAdmin 类):

Now set the autocomplete_view on the ModelAdmin class that the autocomplete is displaying results for (not the ModelAdmin class where you specify autocomplete_fields):

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

因此,如果您有一个名为 YourModelAdmin autocomplete_fields = ['something'] ModelAdmin 类,则应设置 autocomplete_view表示 Something 模型的相应 ModelAdmin 类.

So if you have a ModelAdmin class called YourModelAdmin with autocomplete_fields = ['something'], you would set the autocomplete_view for the corresponding ModelAdmin class for your Something model.

这篇关于更改Django autocomplete_fields标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆