Django 管理 - 在选择字段上使用自动完成和过滤(不是 ManyToMany 或foreignkey)

问题描述 投票:0回答:2

这是我的模型:

class Academic(models.Model):

SCHOOL_COLLEGE_SERVICE = [
    ('School Of Humanities', 'School Of Humanities'),
    ('School Of Culture & Creative Arts', 'School Of Culture & Creative Arts'),
    ('School Of Modern Languages & Cultures', 'School Of Modern Languages & Cultures'),
    ('School Of Critical Studies', 'School Of Critical Studies'),
    ('Arts  College Of Arts Administration', 'Arts  College Of Arts Administration'),
    ]

school = models.CharField(choices=SCHOOL_COLLEGE_SERVICE, max_length=50, blank=True, null=True)

我希望在 Django 管理界面中有一个很好的自动完成/过滤器。不幸的是,如果数据集不是来自多对多或外键关系,则似乎不可能进行自动完成。这是我尝试过的:

from django.contrib import admin
from .models import Academic, Partner, Project
from admin_auto_filters.filters import AutocompleteFilter
import django_filters

@admin.register(Academic)
class AcademicAdmin(admin.ModelAdmin):
    search_fields = ['surname', 'forename']
    #school = django_filters.ChoiceFilter(choices=Academic.SCHOOL_COLLEGE_SERVICE)
    #autocomplete_fields = ['school']

我知道我也可以像这样设置查询集:

class SchoolFilter(django_filters.FilterSet):
    class Meta:
        model = Academic
        fields = ['school',]

但Django仍然抱怨

The value of 'autocomplete_fields[0]' must be a foreign key or a many-to-many field.
我怎样才能实现我想要的?

python django django-admin django-filters django-admin-filters
2个回答
1
投票

您可以使用 django-autocomplete-light 包轻松制作表单 choicefield 作为自动完成下拉列表。这个包还支持查询集。

在 forms.py 中,

class AcademicForm(forms.ModelForm):
    SCHOOL_COLLEGE_SERVICE = [
    ('School Of Humanities', 'School Of Humanities'),
    ('School Of Culture & Creative Arts', 'School Of Culture & Creative Arts'),
    ('School Of Modern Languages & Cultures', 'School Of Modern Languages & Cultures'),
    ('School Of Critical Studies', 'School Of Critical Studies'),
    ('Arts  College Of Arts Administration', 'Arts  College Of Arts Administration'),
    ]
    school = forms.ChoiceField(choices=SCHOOL_COLLEGE_SERVICE,
                               widget=autocomplete.ListSelect2(url='school_autocomplete'))
    
    class Meta:
        model = Academic
        fields = ['school', 'other_your_model_fields']

在 urls.py 中,

urlpatterns = [
    path('school-autocomplete', SchoolAutocompleteView.as_view(), name='school_autocomplete'),
    ]

在views.py中,

from dal import autocomplete

class SchoolAutocompleteView(autocomplete.Select2ListView):

    def get_list(self):
        if not self.request.user.is_authenticated:
            return []

        SCHOOL_COLLEGE_SERVICE = ['School Of Humanities',
                                  'School Of Culture & Creative Arts',
                                  'School Of Modern Languages & Cultures',
                                  'School Of Critical Studies',
                                  'Arts  College Of Arts Administration']

        return SCHOOL_COLLEGE_SERVICE

现在您在管理类中使用 modelform,

@admin.register(Academic)
class AcademicAdmin(admin.ModelAdmin):
    form = AcademicForm
    ....
    ....

有关更多详细信息,doc_link- https://django-autocomplete-light.readthedocs.io/en/master/tutorial.html


0
投票

如果您不想依赖第三方库,这里有一个简单的小部件,可以重用 Django 的自动完成媒体文件(select2):

class AdminAutocompleteSelectWidget(forms.Select):
    def __init__(self, choices=(), attrs=None):
        super().__init__(attrs)
        self.choices = choices

    def render(self, name, value, attrs=None, renderer=None):
        select_html = super().render(name, value, attrs, renderer)
        select2_script = f"""
        <script type="text/javascript">
            (function($) {{
                $(document).ready(function() {{
                    $('#id_{name}').select2();
                }});
            }})(django.jQuery);
        </script>
        """
        return select_html + select2_script

    @property
    def media(self):
        # Reuse the AutocompleteMixin's media files
        return AutocompleteMixin(None, None).media
© www.soinside.com 2019 - 2024. All rights reserved.