{"id":207968,"date":"2014-01-01T01:19:05","date_gmt":"2013-12-31T21:19:05","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=207968"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=207968","title":{"rendered":"<span class=\"post_title\">Django + Select2 = select autocomplete<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t\u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a.<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habr.habrastorage.org\/post_images\/15d\/368\/f0a\/15d368f0aec5d74c72ecdaaf6bc2c21b.png\"\/><br \/>  \u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u0440\u0435\u043c\u044f, \u044f \u043f\u0438\u0448\u0443 \u043d\u0430 django.<\/p>\n<p>  \u0412\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432\u044b\u0432\u043e\u0434\u0430 \u0432 \u0441\u043f\u0438\u0441\u043a\u0430\u0445 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043e\u043f\u0446\u0438\u0439.<br \/>  \u0415\u0441\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u0435 \u0442\u0438\u043f\u0430 models.ForeignKey \u0441\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u043c (Select, SelectMultiple), <br \/>  \u043d\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0438 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<br \/>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u0441\u044f \u043a \u044d\u0442\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e.<\/p>\n<p>  \u041d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u0430\u0445 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430, \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f (\u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0438 \u044d\u0442\u043e \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e).<br \/>  \u0415\u0441\u0442\u044c \u043d\u0430\u0431\u043e\u0440\u044b \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0442\u0438\u043f\u0430 \u00ab\u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u043e\u0442 \u0442\u043e-\u0442\u043e\u00bb \u0438\u043b\u0438 \u00ab\u0432\u043e\u0442 \u044d\u0442\u043e\u00bb<br \/>  \u0412 \u0441\u0432\u044f\u0437\u0438 \u0441 \u044d\u0442\u0438\u043c, \u0440\u0435\u0448\u0438\u043b \u0432\u044b\u043b\u043e\u0436\u0438\u0442\u044c \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c.<\/p>\n<p>  \u0412\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 application \u043f\u043e\u0434 django, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439  <\/p>\n<ul>\n<li>\u0421\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u043f\u043e\u043b\u044f \u0438 \u043f\u043e\u043b\u044f \u0441 \u0434\u0430\u0442\u0430\u043c\u0438<\/li>\n<li>TreeWidget \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0438, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043d\u0430 MPTT<\/li>\n<li>\u0412\u0438\u0434\u0436\u0435\u0442 SelectAutocomplete<\/li>\n<li>\u0412\u0438\u0434\u0436\u0435\u0442 SelectMultipleAutocomplete<\/li>\n<\/ul>\n<p>  \u0421\u0442\u0430\u0442\u044c\u044f \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u043d\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043d\u0435 \u0443\u0441\u043f\u0435\u0432\u0448\u0438\u0445 \u00ab\u043e\u0431\u0440\u0430\u0441\u0442\u0438\u00bb \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043d\u0430 django.<br \/>  \u0414\u0443\u043c\u0430\u044e, \u0447\u0442\u043e \u043e\u043f\u044b\u0442\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u043e\u043d\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430.<br \/>  <a name=\"habracut\"><\/a><\/p>\n<p>  \u0414\u043b\u044f \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0436\u0435\u0442\u0430, \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0448\u0430\u0431\u043b\u043e\u043d \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e <br \/>  {% include &#8216;forms_custom\/tree_widget_modal.html&#8217; %}.<br \/>  \u0415\u0441\u043b\u0438 \u043a\u043e\u043c\u0443-\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u043d\u0435\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435, \u043d\u0430\u043f\u0438\u0448\u0443 \u0432 \u043b\u0438\u0447\u043a\u0443 \u0438\u043b\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u0441\u0442\u043e\u043c.<\/p>\n<p>  \u041e\u043f\u0438\u0448\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432 Select \u0438 SelectMultiple.<br \/>  \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043d\u0435\u0442 \u043f\u043e\u043b\u044f TextAutocomplete, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u043d\u0435 \u043e\u043d\u043e \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u043e\u0441\u044c.<br \/>  \u0414\u0443\u043c\u0430\u044e, \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0433\u043e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, <br \/>  \u0431\u043b\u0430\u0433\u043e \u0432\u0438\u0434\u0436\u0435\u0442\u044b \u0438 \u043f\u043e\u043b\u044f \u0444\u043e\u0440\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u044e\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e.<br \/>  \u0412\u0438\u0434\u0436\u0435\u0442 \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u043c \u043f\u043b\u0430\u0433\u0438\u043d\u0435 Select2 <a href=\"http:\/\/ivaynberg.github.io\/select2\/\">ivaynberg.github.io\/select2\/<\/a><\/p>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/h3>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u043a\u0440\u0438\u043f\u0442\u044b \u0438 \u0441\u0442\u0438\u043b\u0438<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"html\">&lt;link rel=&quot;stylesheet&quot; type=&quot;text\/css&quot; href=&quot;{{ STATIC_URL }}select2\/select2.css&quot;\/&gt;  &lt;!-- \u041b\u0443\u0447\u0448\u0435 \u043e\u0442\u043b\u043e\u0436\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432, \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u044b \u0438\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b (\u0432\u0430\u0448 \u041a.\u041e.) --&gt; &lt;script type=&quot;text\/javascript&quot; src=&quot;{{ STATIC_URL }}jquery\/jquery.min.js&quot;&gt;&lt;\/script&gt; &lt;script type=&quot;text\/javascript&quot; src=&quot;{{ STATIC_URL }}jstree\/jquery.jstree.js&quot;&gt;&lt;\/script&gt; &lt;script type=&quot;text\/javascript&quot; src=&quot;{{ STATIC_URL }}select2\/select2.js&quot;&gt;&lt;\/script&gt;  &lt;!-- \u0421\u043a\u0440\u0438\u043f\u0442\u044b \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u044b \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0434\u043b\u044f \u043e\u0431\u043b\u0435\u0433\u0447\u0435\u043d\u0438\u044f \u0432\u0435\u0441\u0430, \u0435\u0441\u043b\u0438 \u0432\u0434\u0440\u0443\u0433 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043e\u0434\u043d\u043e --&gt; &lt;script type=&quot;text\/javascript&quot; src=&quot;{{ STATIC_URL }}forms_custom\/tree_widget.js&quot;&gt;&lt;\/script&gt; &lt;script type=&quot;text\/javascript&quot; src=&quot;{{ STATIC_URL }}forms_custom\/autocomplete.js&quot;&gt;&lt;\/script&gt; &lt;script type=&quot;text\/javascript&quot; src=&quot;{{ STATIC_URL }}forms_custom\/autocomplete_multiple.js&quot;&gt;&lt;\/script&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442 \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u0432 settings.py (\u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0441\u0442\u0430\u0442\u0438\u043a\u0438 \u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432)<br \/>  \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c urls (\u0434\u043b\u044f \u043e\u0442\u0434\u0430\u0447\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 AJAX)  <\/p>\n<pre><code class=\"python\">    url(r'^forms_custom\/', include('lib.forms_custom.urls', namespace='forms_custom')), <\/code><\/pre>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>  <\/p>\n<pre><code class=\"python\">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'\u041f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0438',                                                  queryset=users_active_qs,                                                 widget=SelectMultipleAutocomplete(queryset=users_active_qs,                                                      expression=&quot;last_name__startswith&quot;))      subject = forms.CharField(label=u'\u0422\u0435\u043c\u0430', required=False)     body = forms.CharField(label=u'\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435', required=False, widget=forms.Textarea)     back_url = forms.CharField(widget=forms.HiddenInput) <\/code><\/pre>\n<p>  \u0412\u0438\u0434\u0436\u0435\u0442 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 QuerySet \u0438 search expression \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430<br \/>  \u0424\u0438\u043b\u044c\u0442\u0440\u044b, \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u044b\u0435 \u043d\u0430 QuerySet \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f.<\/p>\n<p>  \u0421 SelectAutocomplete \u0432\u0441\u0435 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u043d \u0441 \u043f\u043e\u043b\u0435\u043c ModelChoiceField.<br \/>  \u0414\u0430\u043b\u0435\u0435, \u043a\u0430\u043a \u0432\u0441\u0435 \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<h4>\u0412\u0438\u0434\u0436\u0435\u0442<\/h4>\n<p>  \u041c\u0435\u0442\u043e\u0434 \u00abrender\u00bb \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u0442\u043e, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u043e \u043d\u0430 \u0444\u043e\u0440\u043c\u0435, <br \/>  \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u043a\u0440\u044b\u0442\u043e\u0435 \u043f\u043e\u043b\u0435, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0434\u043b\u044f \u00ab\u043d\u0430\u0442\u0440\u0430\u0432\u043b\u0438\u0432\u0430\u043d\u0438\u044f\u00bb \u043d\u0430 \u043d\u0435\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430 select2<\/p>\n<p>  \u041c\u0435\u0442\u043e\u0434 \u00abvalue_from_datadict\u00bb, \u0434\u043e\u0441\u0442\u0430\u0435\u0442 \u0438\u0437 POST-\u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u0430, <br \/>  \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0438\u0445 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u043e\u043b\u044e \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438.<br \/>  \u0422\u0443\u0442 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043a\u0430\u043b\u044f\u0440\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432, \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e <br \/>  \u043d\u0430 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 (\u043a\u0430\u043a \u043e\u0436\u0438\u0434\u0430\u0435\u0442 ModelMultipleChoiceField \u043e\u0442 SelectMultiple),<br \/>  \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e select2 \u0445\u0440\u0430\u043d\u0438\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0432 \u0441\u043a\u0440\u044b\u0442\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u043e\u043b\u0435, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u044f\u0442\u044b\u043c\u0438.<\/p>\n<p>  \u0418\u0437 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439, \u043c\u043e\u0433\u0443 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u044b \u0434\u043e\u0441\u0442\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 WhereNode, <br \/>  \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0437 QuerySet:  <\/p>\n<pre><code class=\"python\">    where_node = self._queryset.query.__dict__['where']     where, where_params = where_node.as_sql(connection.ops.quote_name, connection) <\/code><\/pre>\n<p>  where_params \u043f\u0430\u043a\u0443\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e pickle \u0438 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 where \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0432\u0438\u0434\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 ajax \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"python\">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('&quot;', '\\&quot;')             self._queryset_where_params = pickle.dumps(where_params)         else:             self._queryset_where = &quot;&quot;             self._queryset_where_params = &quot;&quot;   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):         &quot;&quot;&quot; replace scalar value (&quot;1,2,3&quot;) to list ([1,2,3])&quot;&quot;&quot;                  data_dict = super(SelectMultipleAutocomplete, self).value_from_datadict(data, files, name)         value = data_dict[0]                  if not value:             return None          return value.split(&quot;,&quot;)           <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<h4>\u041f\u043e\u043b\u0435 \u0432 \u0444\u043e\u0440\u043c\u0435<\/h4>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e\u043b\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0443\u0436\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 select2  <\/p>\n<pre><code class=\"html\">&lt;input type=&quot;hidden&quot;         id=&quot;{{attrs.id}}&quot;         class=&quot;autocomplete_multiple_widget&quot;         value=&quot;{% if value %}{{value|join:&quot;,&quot;}}{% endif %}&quot;         name=&quot;{{name}}&quot;        data-url=&quot;{% url 'forms_custom:autocomplete_widget' application=application model_name=model_name %}&quot;        data-expression=&quot;{{expression}}&quot;        data-where=&quot;{{where}}&quot;        data-where_params=&quot;{{where_params}}&quot;\/&gt; <\/code><\/pre>\n<h4>\u0421\u043a\u0440\u0438\u043f\u0442<\/h4>\n<p>  \u041e\u0431\u0445\u043e\u0434\u0438\u043c \u0432\u0438\u0434\u0436\u0435\u0442\u044b \u043f\u043e \u043a\u043b\u0430\u0441\u0441\u0443 autocomplete_multiple_widget \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c select2<br \/>  \u0417\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u0430 \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0430\u043c\u043e\u0433\u043e \u0432\u0438\u0434\u0436\u0435\u0442\u0430, \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438<br \/>  id__in=current_values<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">$(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: &quot;\u041f\u043e\u0438\u0441\u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430&quot;,         minimumInputLength: 3,         multiple: true,         ajax: {             url: url,             quietMillis: 1000, \/\/ \u0416\u0434\u0435\u043c 1 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0444\u043b\u0443\u0434\u0438\u0442\u044c             dataType: 'json',             \/\/ \u0412 GET-\u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0438\u0441\u043a\u043e\u043c\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438, \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u043e\u0442\u0431\u043e\u0440\u0430 where \u0438 \u0437\u0430\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b             data: function (term, page) { return {q: term, expression: expression, where: where, where_params: where_params}; },             results: function (data, page) {                 return {results: data};             }         },         \/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0444\u043e\u0440\u043c\u044b         \/\/ \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438\u0437 id (\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0432\u0438\u0434\u0435 value=&quot;1,2,3&quot; \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u0438\u0434\u0436\u0435\u0442\u0430)         \/\/ \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u0438\u0441\u043a id__in=current_values \u0438 \u0447\u0435\u0440\u0435\u0437 callback \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0432\u0438\u0434\u0436\u0435\u0442          initSelection: function(element, callback) {             var id = $(element).val();             if (id !== &quot;&quot;) {                 $.ajax(url, {                     data: {q: id, expression: 'pk__in', where: where, where_params: where_params},                     dataType: &quot;json&quot;                 }).done(function(data) {                      callback(data);                  });             }         },         dropdownCssClass: &quot;bigdrop&quot;,         escapeMarkup: function (m) { return m; }     });  } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<h4>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u043e\u0438\u0441\u043a\u0430<\/h4>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 ajax \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e: \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u043c\u043e\u0434\u0435\u043b\u0438, \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 QuerySet-\u0430<br \/>  \u041f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0436\u0435\u0442\u0430, \u0432 \u043d\u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 pk__in=\u00ab1,2,3\u00bb<br \/>  \u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044d\u0442\u043e\u0433\u043e, \u043c\u044b \u043f\u043e\u0434\u043c\u0435\u043d\u044f\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u043d\u0430 \u0441\u043f\u0438\u0441\u043e\u043a, \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u044f \u043f\u043e \u0437\u0430\u043f\u044f\u0442\u043e\u0439.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"python\">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'\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e ajax')      data = []     expression = request.GET.get('expression')          token = request.GET.get('q')     if expression == u'pk__in':         token = token.split(&quot;,&quot;)      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({&quot;id&quot;: item.id, &quot;text&quot;: unicode(item)})      return HttpResponse(json.dumps(data), content_type=&quot;application\/json;charset=utf-8&quot;)  <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0411\u0435\u0440\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0438\u0437 \u043a\u044d\u0448\u0430 django, \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438, \u0444\u0438\u043b\u044c\u0442\u0440 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0438 \u043e\u0442\u0434\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0430\u0439\u0434\u0435\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432.<br \/>  \u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432\u0438\u0434\u0436\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u0434\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 Select \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <br \/>  \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 (\u043d\u0435 \u043e\u0441\u043e\u0431\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u043f\u0440\u043e\u043c\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043a\u0438 \u0438\u0437 \u0442\u044b\u0441\u044f\u0447 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432) <br \/>  \u0438 \u0441\u043d\u0438\u0437\u0438\u0442 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0432\u0430\u0448\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0443.<\/p>\n<p>  <a href=\"https:\/\/drive.google.com\/file\/d\/0B0GZGIoZAYTFNU9xd3dIR3FXU0k\/edit?usp=sharing\">drive.google.com\/file\/d\/0B0GZGIoZAYTFNU9xd3dIR3FXU0k\/edit?usp=sharing<\/a><\/p>\n<p>  \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.<br \/>  P.S. \u0423\u0441\u043f\u0435\u0448\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0432 \u043d\u043e\u0432\u043e\u043c \u0433\u043e\u0434\u0443, \u043a\u043e\u043c\u0440\u0430\u0434\u044b!    \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/207968\/\"> http:\/\/habrahabr.ru\/post\/207968\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t\u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a.<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habr.habrastorage.org\/post_images\/15d\/368\/f0a\/15d368f0aec5d74c72ecdaaf6bc2c21b.png\"\/><br \/>  \u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u0440\u0435\u043c\u044f, \u044f \u043f\u0438\u0448\u0443 \u043d\u0430 django.<\/p>\n<p>  \u0412\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432\u044b\u0432\u043e\u0434\u0430 \u0432 \u0441\u043f\u0438\u0441\u043a\u0430\u0445 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043e\u043f\u0446\u0438\u0439.<br \/>  \u0415\u0441\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u0435 \u0442\u0438\u043f\u0430 models.ForeignKey \u0441\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u043c (Select, SelectMultiple), <br \/>  \u043d\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0438 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<br \/>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u0441\u044f \u043a \u044d\u0442\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e.<\/p>\n<p>  \u041d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u0430\u0445 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430, \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f (\u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0438 \u044d\u0442\u043e \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e).<br \/>  \u0415\u0441\u0442\u044c \u043d\u0430\u0431\u043e\u0440\u044b \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0442\u0438\u043f\u0430 \u00ab\u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u043e\u0442 \u0442\u043e-\u0442\u043e\u00bb \u0438\u043b\u0438 \u00ab\u0432\u043e\u0442 \u044d\u0442\u043e\u00bb<br \/>  \u0412 \u0441\u0432\u044f\u0437\u0438 \u0441 \u044d\u0442\u0438\u043c, \u0440\u0435\u0448\u0438\u043b \u0432\u044b\u043b\u043e\u0436\u0438\u0442\u044c \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c.<\/p>\n<p>  \u0412\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 application \u043f\u043e\u0434 django, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439  <\/p>\n<ul>\n<li>\u0421\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u043f\u043e\u043b\u044f \u0438 \u043f\u043e\u043b\u044f \u0441 \u0434\u0430\u0442\u0430\u043c\u0438<\/li>\n<li>TreeWidget \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0438, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043d\u0430 MPTT<\/li>\n<li>\u0412\u0438\u0434\u0436\u0435\u0442 SelectAutocomplete<\/li>\n<li>\u0412\u0438\u0434\u0436\u0435\u0442 SelectMultipleAutocomplete<\/li>\n<\/ul>\n<p>  \u0421\u0442\u0430\u0442\u044c\u044f \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u043d\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043d\u0435 \u0443\u0441\u043f\u0435\u0432\u0448\u0438\u0445 \u00ab\u043e\u0431\u0440\u0430\u0441\u0442\u0438\u00bb \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043d\u0430 django.<br \/>  \u0414\u0443\u043c\u0430\u044e, \u0447\u0442\u043e \u043e\u043f\u044b\u0442\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u043e\u043d\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-207968","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/207968","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=207968"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/207968\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=207968"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=207968"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=207968"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}