在Django2.0中,添加了autocomplete_fields,这很棒。
没有autocomplete_fields,我可以使用formfield_for_foreignkey更改ForeignKeyField的查询集。
但是将两者结合在一起是行不通的--看起来自动补全的选项列表是动态的,并且来自不同的url,而不是来自当前的表单。
所以问题是-
如何更改自动完成小部件中的查询集?
发布于 2018-01-08 23:31:14
重写ModelAdmin的get_search_results
方法以使用所需的查询。您可以在为自动补全字段提供数据的视图的get_queryset
方法中看到,该方法用于获取查询集-此答案的源是https://github.com/django/django/blob/03dbdfd9bbbbd0b0172aad648c6bbe3f39541137/django/contrib/admin/views/autocomplete.py#L42。
发布于 2019-05-21 03:06:57
如果对'self‘上的ManyToManyField
使用autocomplete_fields
,则此示例将排除当前对象。
通过重写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
发布于 2020-06-14 20:05:07
不知何故,我遇到了同样的问题,当我使用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对象的情况下。所以我们就去
# moodels.py
class model_A(models.Model):
name = models.CharField()
class model_B(models.Model):
name = models.CharField()
fk_field = models.OneToOneField( #ManyToManyField or ForeignKey
model_A,
related_name='fk_reverse',
on_delete=models.CASCADE)
# admin.py
class model_A_Admin(admin.ModelAdmin):
search_fields = ('name', )
def get_search_results(self, request, queryset, search_term):
import re
queryset, use_distinct = super().get_search_results(request, queryset, search_term)
# note: str(request.META.get('HTTP_REFERER')) is the url from which the request had come/previous url.
if "model_b/add/" in str(request.META.get('HTTP_REFERER')):
# if we were in creating new model_B instanse page
# note: the url is somehow containing model_Bs calss name then / then "add"
# so there is no related object(of model_A) for non exsisting object(of model_B)
queryset = self.model.objects.filter(fk_reverse=None)
elif re.search(r"model_b/\d/change/", str(request.META.get('HTTP_REFERER'))):
# if we were in updatineg page of an exsisting model_B instanse
# the calling page url contains the id of the model_B instanse
# we are extracting the id and use it for limitaion proccess
pk = int(re.findall(r'\d+', str(str(request.META.get('HTTP_REFERER')).split('/')[-3: ]))[-1])
queryset = self.model.objects.filter(fk_reverse=pk)
return queryset, use_distinct
https://gist.github.com/mh-firouzjaah/48dceae592d4b4275fa31d37ac77ff69
https://stackoverflow.com/questions/48152908
复制相似问题