Last active
September 25, 2024 08:02
Revisions
-
cb109 revised this gist
Feb 12, 2021 . No changes.There are no files selected for viewing
-
cb109 revised this gist
Feb 12, 2021 . 2 changed files with 24 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,7 @@ <!-- To make the AutocompleteSelect work we need to include some CSS and javascript --> {{ autocomplete_form.media }} <form id="mycustommodel_form"> {{ autocomplete_form }} <button type="submit">Submit</button> </form> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,19 +1,38 @@ from typing import Callable from typing import Iterable from django.http import JsonResponse from myproject.myapp.forms import MyCustomModelForm from myproject.myapp.models import MyCustomModel from myproject.myapp.utils import search def make_autocomplete_response( queryset: Iterable, instance_to_text_func: Callable ) -> JsonResponse: return JsonResponse( { "results": [ {"id": instance.id, "text": instance_to_text_func(instance)} for instance in queryset ], "pagination": {"more": False}, } ) def search_mycustommodel(request): term = request.GET.get("term", "") candidates = search(MyCustomModel.objects, term, ["name"]).order_by( "name", ) return make_autocomplete_response( candidates, lambda instance: instance.name ) def template(request, pk: int): instance = MyCustomModel.objects.get(pk=pk) autocomplete_form = MyCustomModelForm( initial={"mycustommodel": instance}, -
cb109 revised this gist
Feb 12, 2021 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,4 @@ from myproject.myapp.forms import MyCustomModelForm from myproject.myapp.models import MyCustomModel from myproject.myapp.utils import search @@ -14,7 +15,7 @@ def search_mycustommodel(request): def template(request, pk): instance = MyCustomModel.objects.get(pk=pk) autocomplete_form = MyCustomModelForm( initial={"mycustommodel": instance}, ) return render_to_response( -
cb109 created this gist
Feb 12, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,74 @@ from typing import Iterable from typing import Optional from django.contrib import admin from django.contrib.admin.widgets import AutocompleteSelect from django.forms import ModelChoiceField from myproject.myapp.models import MyCustomModel class CustomUrlAutocompleteSelect(AutocompleteSelect): """URL is not based on url_name implicitly, instead passed in as a kwarg.""" def __init__(self, *args, **kwargs): self.url = kwargs.pop("url") super().__init__(*args, **kwargs) def get_url(self): return self.url def build_modelchoicefield( autocomplete_url: str, model: type, fieldname: str, queryset: Iterable, label: Optional[str] = None, required: bool = False, ) -> ModelChoiceField: # FIXME: # Our shenanigans to use the AutocompleteSelect outside of the # admin have a little drawback here: The queryset that we pass # will be used to check for a valid selection, but it is not # what the API returns, so it will not affect what we see in # the dropdown, unfortunately. It will however be respected # when we submit the form and display an error 'invalid # selection'. options = { "queryset": queryset, "widget": CustomUrlAutocompleteSelect( model._meta.get_field(fieldname).remote_field, admin.site, url=autocomplete_url, ), "required": required, } if label: options["label"] = label return ModelChoiceField(**options) class MyCustomModelForm(forms.ModelForm): """Note: Make sure to include {{ form.media }} in the template.""" class Meta: model = MyCustomModel fields = ("id",) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["id"] = build_modelchoicefield( autocomplete_url="/autocomplete/mycustommodel", model=MyCustomModel, fieldname="id", queryset=MyCustomModel.objects.all(), required=False, ) # HACK: Rename field to use a less generic input name in html, # otherwise the selet would have name="id". self.fields["mycustommodel"] = self.fields["id"] del self.fields["id"] This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,7 @@ <!-- To make the AutocompleteSelect work we need to include some CSS and javascript --> {{ select_workspace_form.media }} <form id="mycustommodel_form"> {{ select_workspace_form }} <button type="submit">Submit</button> </form> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,10 @@ ... urlpatterns = [ ... url( r"^autocomplete/mycustommodel$", myproject.myapp.views.search_mycustommodel, ), ... ] This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,23 @@ from myproject.myapp.models import MyCustomModel from myproject.myapp.utils import search def search_mycustommodel(request): term = request.GET.get("term", "") candidates = search(Workspace.objects, term, ["name"]).order_by( "name", ) return make_autocomplete_response( workspace_candidates, lambda workspace: workspace.name ) def template(request, pk): instance = MyCustomModel.objects.get(pk=pk) autocomplete_form = SelectWorkspaceForm( initial={"mycustommodel": instance}, ) return render_to_response( "myapp/template.html", {"autocomplete_form": autocomplete_form} )