Ben*_*min 10 python django python-3.x
我ModelAdmin在Django 2.1.3中有这样的:
class BoxAdmin(admin.ModelAdmin):
    autocomplete_fields = ['testkit']
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'testkit':
            kwargs['queryset'] = Barcode.objects.exclude(testkit__in=Box.objects.all().values('testkit'))
        return super().formfield_for_foreignkey(db_field, request, **kwargs)
该formfield_for_foreignkey方法是为"传统"外键字段编写的.对于自动完成字段,它确保在选择查询集之外的测试工具包时显示错误.但是,它不会限制自动填充字段中的结果.该文档未提及对自定义查询集的任何限制.这个答案是相关的,但仅涉及授权.
可以覆盖get_search_result相关的方法ModelAdmin.
class TestkitAdmin(admin.ModelAdmin):
    search_fields = ['number']
    def get_search_results(self, request, queryset, search_term):
        queryset, use_distinct = super().get_search_results(request, queryset, search_term)
        if 'autocomplete' in request.path:
            queryset = queryset.exclude(testkit__in=Box.objects.all().values('testkit'))
        return queryset, use_distinct
但我找不到确定搜索请求来自哪个自动填充字段的方法.因此,我只能对其进行编程以满足一个引用的需要ModelAdmin.
如何正确限制自动填充字段的查询集?
这个问题看起来很棘手,但我看到很多人一直在问这个问题,而其他人则给出了非常复杂的答案。
\n那么限制自动完成列表的最简单方法是通过附加 get_search_results \ nor the get_queryset inside the related object\xe2\x80\x99s ModelAdmin来限制查询集
\n现在要知道您的自动完成字段何时调用它,您有:
\n那么你的代码应该是这样的:
\nclass TestkitAdmin(admin.ModelAdmin):\n    search_fields = ['number']\n\n    def get_search_results(self, request, queryset, search_term):\n        queryset, use_distinct = super().get_search_results(request, queryset, search_term)\n        if 'autocomplete' in request.path and request.GET.get('model_name') == 'box' and request.GET.get('field_name') == 'testkit':\n            queryset = queryset.exclude(testkit__in=Box.objects.all().values('testkit'))\n        return queryset, use_distinct\n您可以覆盖 Djangoautocomplete.js静态文件static/admin/js/autocomplete.js。Django 总是更喜欢您覆盖的文件。  
然后在覆盖的文件中修改djangoAdminSelect2()函数如下:
$.fn.djangoAdminSelect2 = function(options) {
    var settings = $.extend({}, options);
    $.each(this, function(i, element) {
        var $element = $(element);
        $.extend(settings, {
            'ac_field_name': $element.parents().filter('.related-widget-wrapper').find('select').attr('name')
        });
        init($element, settings);
    });
    return this;
};
和init()这样的函数:
var init = function($element, options) {
    var settings = $.extend({
        ajax: {
            data: function(params) {
                return {
                    term: params.term,
                    page: params.page,
                    field_name: options.ac_field_name
                };
            }
        }
    }, options);
    $element.select2(settings);
};
然后在您get_search_results()只需访问请求 GET 参数field_name即可。  
当然你可以让JS看起来更好,但原则上它是这样工作的。
| 归档时间: | 
 | 
| 查看次数: | 460 次 | 
| 最近记录: |