encode / django-rest-framework

Web APIs for Django. 🎸
https://www.django-rest-framework.org
Other
28.34k stars 6.84k forks source link

Better support for autocomplete inputs is planned in future versions. #5079

Closed jpic closed 3 years ago

jpic commented 7 years ago

I've seen in the documentation that:

Better support for autocomplete inputs is planned in future versions.

I have found no open issue about it and the last discussion I found in the ML archives about autocompletes is from 2014.

Is it possible to start a discussion about what "better support for autocomplete inputs" would look like, and see what we can do in DAL or DRF to help ? (note: i maintain DAL since 2012, hence my personal interrest)

<3

jpic commented 7 years ago

Integrating DAL with DF was nice: https://gist.github.com/jpic/e4f48295ab419d007826d1ab510a77a2

But DAL doesn't load jQuery, what's your recommendation here ?

tomchristie commented 7 years ago

The browsable API does include jQuery, so I assume that's not a problem.

I guess that we'd need:

Presumably there also needs to be an autocomplete endpoint against which the search requests are issued, right?

rpkilby commented 7 years ago

@tomchristie - given that widgets now use templates for rendering, would it make sense to revert to using widgets in serializers? It would make integration w/ 3rd party packages like DAL fairly trivial.

xordoquy commented 7 years ago

@rpkilby depends on how it's done. I'm not willing to increase the coupling between Serializers and Django itself through the widgets. However, keeping this within the scope of the HTML renderer is fine for me.

rpkilby commented 7 years ago

For cases like DAL, you would need to include field-specific information. eg,

widget=autocomplete.ModelSelect2Multiple(url='posts:poster_autocomplete')

I don't think this could be accomplished by the renderer alone, since it will lack that context.

jpic commented 7 years ago

Currently, {% crispy filter.form %} in django_filter_crispyforms.html renders the form media.

In the DOM chronology, this happens before DRF's base.html loads jQuery, so, the filter form media cannot rely on the jQuery instance:

<h2>Field filters</h2>

<form  method="get" > <link href="/collected/autocomplete_light/vendor/select2/dist/css/select2.3805311d5fc1.css" type="text/css" media="all" rel="stylesheet" />
<link href="/collected/autocomplete_light/select2.d64f3c111aa6.css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="/collected/autocomplete_light/jquery.init.d1f8bdc7bbb0.js"></script>
<script type="text/javascript" src="/collected/autocomplete_light/autocomplete.init.22849fbfbdfe.js"></script>
<script type="text/javascript" src="/collected/autocomplete_light/vendor/select2/dist/js/select2.full.9c2f3bbf136f.js"></script>
<script type="text/javascript" src="/collected/autocomplete_light/select2.51da6b06154b.js"></script> <div id="div_id_account" class="form-group"> <label for="id_account" class="control-label ">
                Account
<!-- ..... -->

      <script>
        window.drf = {
          csrfHeaderName: "X-CSRFTOKEN",
          csrfCookieName: "csrftoken"
        };
      </script>
      <script src="/collected/rest_framework/js/jquery-1.12.4.min.4f252523d4af.js"></script>
      <script src="/collected/rest_framework/js/ajax-form.8b39b42cbf4e.js"></script>
      <script src="/collected/rest_framework/js/csrf.753b7a1f2ee7.js"></script>
      <script src="/collected/rest_framework/js/bootstrap.min.5869c96cc8f1.js"></script>
      <script src="/collected/rest_framework/js/prettify-min.709bfcc456c6.js"></script>
      <script src="/collected/rest_framework/js/default.b846d7d305c9.js"></script>
      <script>
        $(document).ready(function() {
          $('form').ajaxForm();
        });
      </script>

  </body>

</html>

If only we could find a way to make the filter form media load after base.html loads jQuery, then users would just have to create filter sets as such:

class PostFilter(FilterSet):
    poster = django_filters.ModelMultipleChoiceFilter(
        queryset=Poster.objects.all(),
        widget=autocomplete.ModelSelect2Multiple(url='url-name'),
    )   

And it will work ootb, provided they have registered a compatible autocomplete view on whatever url-name reverses to - this also delegates security to the user when they register the view.

Would this work for you ?

I didn't understand why we'd need to create new templates though, are you talking about it for integration /without/ django-filter ?