I spent a few hours trying to understand why my code (built on @Tim 's answer) would not work, until I stumble on a comment about missing references to css/js files.
Here is a complete working solution to use the AutocompleteSelect widget in any custom form for signed-in users having both 'staff' and 'view' access to the given model:
from django.urls import reverse
from django.contrib.admin.widgets import AutocompleteSelect
from django.contrib import admin
class UserAutocompleteSelect(AutocompleteSelect):
def get_url(self):
model = CustomUser
return reverse(self.url_name % (self.admin_site.name, model._meta.app_label, model._meta.model_name))
class UserChoiceField(forms.ModelChoiceField):
def __init__(self, queryset=None, widget=None, **kwargs):
if queryset is None:
queryset = CustomUser.objects.all()
if widget is None:
widget = UserAutocompleteSelect(None, admin.site) # pass `None` for `rel`
super().__init__(queryset, widget=widget, **kwargs)
class UserAutocompleteSelectForm(forms.ModelForm):
"""
for changing user on Play objects
using amdin module autocomplete
"""
user = UserChoiceField(
# queryset=CustomUser.objects.all(),
help_text=_('Select the user to replace the current one')
)
class Meta:
model = Play
fields = ('user', )
You can use the same, replacing CustomUser
and Play
by your own models
If (like me) this is not working out-of-the-box with the html template you're using, that means that you need to include the required css/js files to your template. Here is a simple way to do it :
Providing that the form is declared as such in the view:
form = UserAutocompleteSelectForm()
...
context = {
'form': form,
...
}
return render(request, 'users/change_user.html', context)
you should add the following lines to the html template to include the required css/js files:
{% block extrahead %}
{{ block.super }}
{{ form.media }}
{% endblock %}
autocomplete_fields = ('your_field',)
– Hoppe