如何过滤Django2的autocomplete_fields中的选项?

时间:2018-01-08 15:04:29

标签: python django django-admin django-2.0

在Django 2.0中,添加了autocomplete_fields,这很棒。

如果没有autocomplete_fields,我可以使用formfield_for_foreignkey更改ForeignKeyField的查询集。

但将两者结合起来并不起作用 - 看起来自动完成的选项列表是动态的,来自不同的网址,而不是来自当前的表单。

所以问题是 -

如何更改自动填充小部件中的查询集?

4 个答案:

答案 0 :(得分:2)

覆盖ModelAdmin的get_search_results方法以使用您想要的查询。您可以在get_queryset方法中查看视图,该视图提供了用于获取查询集的自动填充字段的数据 - 此答案的来源为https://github.com/django/django/blob/master/django/contrib/admin/views/autocomplete.py#L42,但我不希望这样链接说正确的时间。

答案 1 :(得分:2)

简短:您可以在django-admin-autocomlete-all中尝试我的解决方案,或者做类似的事情。

长答案:

一个痛苦是:源外键的limit_choices_to- ..也没有实现:(

我能够对目标ModelAdmin的get_search_results()实施过滤器。 但是在这里,我们还有另一个严重的痛苦。 我们可以检查request.is_ajax and '/autocomplete/' in request.path

此外,我们只有request.headers ['Referer']。借助于此,我们可以将受影响的外键限制为1个模型。 但是,如果我们有2个以上的外键进入同一目标(让我们说:在同一模型实例中有两个用户角色),则我们不知道其中哪个调用ajax。

我的想法是修改网址。使用Request url失败(长时间尝试在DOM和js中找到select2元素并扩展url)。

但是我使用window.history.replaceState()修改了Referer url(即源管理页面url)取得了一些成功。我可以临时修改网址,例如/?key=author-如果您将使用 django-admin-autocomplete-all ,该网址将始终运行,并且我可以使用其他自定义JavaScript将几乎所有内容添加到Referer网址中。特别是添加其他表单字段的当前值可能对实现动态过滤(字段的依赖性)很有用。

所以,这确实是一个hack。但是您可以尝试使用django-admin-autocomplete-all。 -有关此文档的更多信息。

答案 2 :(得分:1)

我遇到了同样的问题,当使用autocomplete_fields时,limit_choices_to没有生效,然后我找到了一种解决方案,可能对其他人也有帮助。 这是我的想法和解决方案,任何人都应该更改其使用代码。

想象一下,我们有两个模型model_A和modle_B: 我们将覆盖
的“ get_search_results” model_A的模型管理员(因为model_B有一个foreign_key(或m2m)) 就我而言,我只想将选择限制在所有
的model_A对象上 当前没有model_B连接的对象 或在将model_B的对象更新为仅限于先前的model_A对象的情况下。 所以我们走

require (
  ...
  github.com/y  version
  ...
)

replace github.com/y version => github.com/x your-fork-version


https://gist.github.com/mh-firouzjaah/48dceae592d4b4275fa31d37ac77ff69

答案 3 :(得分:0)

如果您将autocomplete_fields用于{self}上的ManyToManyField, 此示例将排除当前对象。

通过覆盖get_form获取当前对象的ID:

field_for_autocomplete = None

def get_form(self, request, obj=None, **kwargs):
    if obj:
        self.field_for_autocomplete = obj.pk

    return super(MyAdmin, self).get_form(request, obj, **kwargs)

接下来,覆盖get_search_results。仅针对模型的自动完成URI修改查询集:

def get_search_results(self, request, queryset, search_term):
    queryset, use_distinct = super().get_search_results(request, queryset, search_term)

    # Exclude only for autocomplete
    if request.path == '/admin/myapp/mymodel/autocomplete/':
        queryset = queryset.exclude(field=self.field_for_autocomplete)

    return queryset, use_distinct