<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}select2/select2.css"/> <!-- , ( ..) --> <script type="text/javascript" src="{{ STATIC_URL }}jquery/jquery.min.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}jstree/jquery.jstree.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}select2/select2.js"></script> <!-- , , - --> <script type="text/javascript" src="{{ STATIC_URL }}forms_custom/tree_widget.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}forms_custom/autocomplete.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}forms_custom/autocomplete_multiple.js"></script>
url(r'^forms_custom/', include('lib.forms_custom.urls', namespace='forms_custom')),
from django import forms from django.contrib.auth import get_user_model from lib.forms_custom.widgets import SelectMultipleAutocomplete users_active_qs = get_user_model().objects.filter(is_active=True) class MessageCreateForm(forms.Form): recepients = forms.ModelMultipleChoiceField(label=u'', queryset=users_active_qs, widget=SelectMultipleAutocomplete(queryset=users_active_qs, expression="last_name__startswith")) subject = forms.CharField(label=u'', required=False) body = forms.CharField(label=u'', required=False, widget=forms.Textarea) back_url = forms.CharField(widget=forms.HiddenInput)
where_node = self._queryset.query.__dict__['where'] where, where_params = where_node.as_sql(connection.ops.quote_name, connection)
import datetime from django import forms from django.db import connection from django.forms import widgets as widgets_django from django.forms import fields from django.template.loader import render_to_string from django.forms.widgets import HiddenInput import pickle class AutocompleteWidget(object): def _parse_queryset(self): self._application = self._queryset.model.__module__.split('.')[-0] self._model_name = self._queryset.model.__name__ where_node = self._queryset.query.__dict__['where'] where, where_params = where_node.as_sql(connection.ops.quote_name, connection) if where: self._queryset_where = where.replace('"', '\"') self._queryset_where_params = pickle.dumps(where_params) else: self._queryset_where = "" self._queryset_where_params = "" class SelectAutocomplete(widgets_django.Select, AutocompleteWidget): def __init__(self, queryset, attrs=None): super(SelectAutocomplete, self).__init__(attrs) self._queryset = queryset self._parse_queryset() def render(self, name, value, attrs=None, choices=()): application = self._queryset.model.__module__.split('.')[-0] model_name = self._queryset.model.__name__ return render_to_string('forms_custom/autocomplete.html', {'value': value, 'attrs': attrs, 'application': application, 'model_name': model_name, 'expression': 'title__startswith', 'name': name, 'where': self._queryset_where, 'where_params': self._queryset_where_params }) class SelectMultipleAutocomplete(widgets_django.SelectMultiple, AutocompleteWidget): def __init__(self, queryset, attrs=None, expression='title__startswith'): super(SelectMultipleAutocomplete, self).__init__(attrs) self._queryset = queryset self._expression = expression self._parse_queryset() def render(self, name, value, attrs=None, choices=()): return render_to_string('forms_custom/autocomplete_multiple.html', {'value': value, 'attrs': attrs, 'application': self._application, 'model_name': self._model_name, 'expression': self._expression, 'name': name, 'where': self._queryset_where, 'where_params': self._queryset_where_params }) def value_from_datadict(self, data, files, name): """ replace scalar value ("1,2,3") to list ([1,2,3])""" data_dict = super(SelectMultipleAutocomplete, self).value_from_datadict(data, files, name) value = data_dict[0] if not value: return None return value.split(",")
<input type="hidden" id="{{attrs.id}}" class="autocomplete_multiple_widget" value="{% if value %}{{value|join:","}}{% endif %}" name="{{name}}" data-url="{% url 'forms_custom:autocomplete_widget' application=application model_name=model_name %}" data-expression="{{expression}}" data-where="{{where}}" data-where_params="{{where_params}}"/>
$(document).ready(function() { $('.autocomplete_multiple_widget').each(function() { bind_autocomplete_multiple_widget(this); }); }); function bind_autocomplete_multiple_widget(element) { var j_element = $(element); url = j_element.attr('data-url'); var expression = j_element.attr('data-expression'); var where = j_element.attr('data-where'); var where_params = j_element.attr('data-where_params'); $(element).select2({ placeholder: " ", minimumInputLength: 3, multiple: true, ajax: { url: url, quietMillis: 1000, // 1 , dataType: 'json', // GET- , where data: function (term, page) { return {q: term, expression: expression, where: where, where_params: where_params}; }, results: function (data, page) { return {results: data}; } }, // // id ( value="1,2,3" ) // id__in=current_values callback initSelection: function(element, callback) { var id = $(element).val(); if (id !== "") { $.ajax(url, { data: {q: id, expression: 'pk__in', where: where, where_params: where_params}, dataType: "json" }).done(function(data) { callback(data); }); } }, dropdownCssClass: "bigdrop", escapeMarkup: function (m) { return m; } }); }
import json import pickle from django.http import HttpResponse, HttpResponseForbidden from django.db.models.loading import get_model def autocomplete_widget(request, application, model_name): if not request.is_ajax(): return HttpResponseForbidden(u' ajax') data = [] expression = request.GET.get('expression') token = request.GET.get('q') if expression == u'pk__in': token = token.split(",") objects = get_model(application, model_name).objects where = request.GET.get('where') if where: where_params = request.GET.get('where_params') where_params = pickle.loads(where_params) objects = objects.extra(where=[where], params=where_params) objects = objects.filter(**{expression: token})[:20] for item in objects.iterator(): data.append({"id": item.id, "text": unicode(item)}) return HttpResponse(json.dumps(data), content_type="application/json;charset=utf-8")
Source: https://habr.com/ru/post/207968/
All Articles