我在Django 2.1.3中有一个ModelAdmin
,如下所示:
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
方法是为“传统”外键字段编写的。对于自动完成字段,它确保在选择查询集之外的测试包时显示错误。但是,它并不限制在自动完成字段中找到的结果。 documentation没有提到对自定义查询集的任何限制。 This answer是相关的,但仅涉及授权。
可以覆盖相关ModelAdmin
的{{3}}方法。
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
的需求。
如何正确限制自动完成字段的查询集?
答案 0 :(得分:0)
您可以在autocomplete.js
中覆盖Django 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看起来更好,但原则上它是这样工作的。