рд╣рд╛рдп, рд╣реИрдмреНрд░ред
рдЕрдкрдиреЗ рдЖрдЦрд┐рд░реА
рд▓реЗрдЦ рдореЗрдВ, рдореИрдВрдиреЗ Django рдореЗрдВ рдЯреИрдЧ рджрд░реНрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╕реНрдЯрдо рдлрд╝реАрд▓реНрдб рдмрдирд╛рдиреЗ рдХреА рддрдХрдиреАрдХ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ред рдЕрдм рдореИрдВ рдПрдХ рддреИрдпрд╛рд░ рдФрд░ рдЕрдзрд┐рдХ рдпрд╛ рдХрдо рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╕рдорд╛рдзрд╛рди рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдЬреЛ рдХрд┐ AJAX рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдСрдЯреЛ-рдкреВрд░реНрддрд┐ рдХреЗ рд╕рд╛рде рдХрдИ рд╡рд┐рдХрд▓реНрдк рдХреНрд╖реЗрддреНрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдлрд╝реАрд▓реНрдб рдФрд░ рдкрд┐рдЫрд▓реЗ рдЖрд▓реЗрдЦ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╕реЗ рдЖрдЗрдЯрдо рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдирдП рдирд╣реАрдВ рдмрдирд╛рддрд╛ рд╣реИред рдЕрджреНрднреБрдд jQuery рдкреНрд▓рдЧрдЗрди
Select2 рд╕рд╛рдордиреЗ рдХреЗ рдЕрдВрдд рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрдЧрд╛ред рд╕рдорд╛рдзрд╛рди рдПрдХ рдЕрд▓рдЧ Django рдЖрд╡реЗрджрди рдХреЗ рд░реВрдк рдореЗрдВ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рд╡рд┐рдЬреЗрдЯ
from django.forms.widgets import Widget from django.conf import settings from django.utils.safestring import mark_safe from django.template.loader import render_to_string class InfiniteChoiceWidget(Widget): '''Infinite choice widget, based on Select2 jQuery-plugin (http://ivaynberg.imtqy.com/select2/)''' class Media: js = ( settings.STATIC_URL + "select2/select2.js", ) css = { 'all': (settings.STATIC_URL + 'select2/select2.css',) } def __init__(self, data_model, multiple=False, disabled=False, attrs=None): super(InfiniteChoiceWidget, self).__init__(attrs) self.data_model = data_model self.multiple = multiple self.disabled = disabled def render(self, name, value, attrs=None): return mark_safe(render_to_string("infinite_choice_widget.html", {"disabled": self.disabled, "multiple": self.multiple, "attrs": attrs, "app_name": self.data_model._meta.app_label, "model_name": self.data_model.__name__, "input_name": name, "current_value": value if value else "", }) )
рд╡рд┐рдЬреЗрдЯ рдирд┐рд░реНрдорд╛рддрд╛ рдПрдХ рдореЙрдбрд▓ рд╡рд░реНрдЧ, рдПрдХрд╛рдзрд┐рдХ рдФрд░ рдЕрдХреНрд╖рдо рдЭрдВрдбреЗ, рдЬреЛ рдХреНрд░рдорд╢рдГ рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИрдВ, рдЪрдпрди рдФрд░ рдХреНрд╖реЗрддреНрд░ рдХреА рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреА рдмрд╣реБрд▓рддрд╛ рдХреЗ рд▓рд┐рдП рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдореАрдбрд┐рдпрд╛ рдЙрдкрд╡рд░реНрдЧ Select2 рд▓рд┐рдкрд┐рдпреЛрдВ рдФрд░ рд╢реИрд▓рд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред Select2 рдкреНрд▓рдЧрдЗрди рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рд╡рд╛рд▓реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ infinite_choice_widget.html рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
{% load url from future %} {# django 1.5 #} <input type="hidden" {% for key,value in attrs.iteritems %} {{key}}="{{value}}" {% endfor %} name="{{input_name}}" value="{{current_value}}" /> {# Settings for Select2 #} <script type="text/javascript"> $("#{{attrs.id}}").select2({ multiple: {{multiple|yesno:"true,false"}}, formatInputTooShort: function (input, min) { return ", " + (min - input.length) + " "; }, formatSearching: function () { return "..."; }, formatNoMatches: function () { return " "; }, minimumInputLength: 3, initSelection : function (element, callback) { $.ajax({ url: "{% url 'infinite_choice_data' app_name model_name %}", type: 'GET', dataType: 'json', data: {ids: element.val()}, success: function(data, textStatus, xhr) { callback(data); }, error: function(xhr, textStatus, errorThrown) { callback({}); } }); }, ajax: { url: "{% url 'infinite_choice_data' app_name model_name %}", dataType: 'json', data: function (term, page) { return {term: term, </script>
рдпрд╣рд╛рдВ рдХреЗрдВрджреНрд░реАрдп рд╡рд╕реНрддреБ рдПрдХ рдЫрд┐рдкрд╛ рд╣реБрдЖ рдЗрдирдкреБрдЯ рд╣реИ, рдЬреЛ рдЪрдпрдирд┐рдд рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдЧрд╛ред рдФрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА #id рдкрд░ рдЗрд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ Select2 рдкреНрд▓рдЧрдЗрди рдЗрд╕рдХреЗ рдЦрд┐рд▓рд╛рдл рд╕реЗрдЯ рд╣реИред
рдЪрд▓реЛ рдкреНрд▓рдЧрдЗрди рдорд╛рдкрджрдВрдбреЛрдВ рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВред
- рдПрдХрд╛рдзрд┐рдХ - рдХрдИ рд╡рд┐рдХрд▓реНрдк рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЛ рд╕рдХреНрд╖рдо / рдЕрдХреНрд╖рдо рдХрд░рддрд╛ рд╣реИ
- formatInputTooShort - рд╕реНрд╡рдд: рдкреВрд░реНрдгрддрд╛ рдЯреНрд░рд┐рдЧрд░ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐рддрдиреЗ рд╡рд░реНрдгреЛрдВ рдХреЛ рджрд░реНрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд▓реМрдЯрд╛рддрд╛ рд╣реИ
- formatSearching - рдпрд╣ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдЦреЛрдЬ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЬрд╛рд░реА рд╣реИ
- formatNoMatches - рдирд┐рд░рд╛рд╢рд╛рдЬрдирдХ рд╕реЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ ...
- рдиреНрдпреВрдирддрдордЗрдиреНрдлреНрд▓реЗрдореЗрдЯреНрд░реА - рд╕реНрд╡рдд: рдкреВрд░реНрдгрддрд╛ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдиреНрдпреВрдирддрдо рд╡рд░реНрдг рджрд░реНрдЬ рдХрд┐рдП рдЧрдП
- initSelection - рдпрджрд┐ рдкреГрд╖реНрда рд▓реЛрдб рдХрд░рддреЗ рд╕рдордп рдЫрд┐рдкреЗ рд╣реБрдП рдлрд╝реАрд▓реНрдб рдореЗрдВ рдХреЛрдИ рдЪрдпрдирд┐рдд рддрддреНрд╡ рд╣реИрдВ, рддреЛ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рд╕рд░реНрд╡рд░ рдХреЛ рдЗрди рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд░реНрд╢рд┐рдд рдирд╛рдореЛрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП AJAX рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИред
- рдЕрдЬрд╛рдХреНрд╕ - рджрд░реНрдЬ рдкрд╛рда рднреЗрдЬрддрд╛ рд╣реИ рдФрд░ рд╡рд╕реНрддреБрдУрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ {рдЖрдИрдбреА: ..., рд╢реАрд░реНрд╖рдХ: ...} рдЬрд┐рд╕рдХрд╛ рд╢реАрд░реНрд╖рдХ рджрд░реНрдЬ рдХрд┐рдП рдЧрдП рдкрд╛рда рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред рд╢рдмреНрдж - рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд┐рдпрд╛, рдкреЗрдЬ_рд▓рд┐рдорд┐рдЯ - рдкреНрд░рджрд░реНрд╢рд┐рдд рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдорд┐рд▓реАред
рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЗрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЗ рдЖрд╡реЗрджрди рдХрд╛ рдирд╛рдо рдФрд░ рдореЙрдбрд▓ рдХрд╛ рдирд╛рдо рдЙрд╕ URL рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдбреЗрдЯрд╛ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЛ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдбреЗрдЯрд╛ рдХрд┐рд╕ рдореЙрдбрд▓ рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╣рдо рдЗрд╕реЗ рд╣рд░ рдмрд╛рд░ рдмрддрд╛рдПрдВрдЧреЗред
рдЕрдВрдд рдореЗрдВ, рд╣рдо рдкреНрд▓рдЧрдЗрди рдХреЛ рдирд┐рд╖реНрдХреНрд░рд┐рдп рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддреЗ рд╣реИрдВ рдпрджрд┐ рд╡рд┐рдЬреЗрдЯ рдирд┐рд╖реНрдХреНрд░рд┐рдп рд╣реЛ рдЧрдпрд╛ рд╣реИ = рд╕рд╣реАред
рд╕реНрд╡рддрдГ рдкреВрд░реНрдг рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рд╕рдмрдорд┐рд╢рди
рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдХрд╣рд╛, рджреГрд╢реНрдп рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХрд┐рд╕ рдореЙрдбрд▓ рд╕реЗ рдбреЗрдЯрд╛ рд▓реЗрдирд╛ рд╣реИред рдореЙрдбрд▓ рдХреНрд▓рд╛рд╕ рдХреЛ рдЬрд╛рдиреЗ-рдорд╛рдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдирд╛рдо рдФрд░ рдореЙрдбрд▓ рдХреНрд▓рд╛рд╕ рдХреЗ рдирд╛рдо рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдорд╛рдирдХ рддрд░реАрдХрд╛ рд╣реИ, рд╣рдо рдЗрди рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рджреГрд╢реНрдп рдореЗрдВ рдкрд╛рд╕ рдХрд░рдХреЗ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
from django.http import Http404, HttpResponse import json from django.db.models import get_model def infinite_choice_data(request, app_name, model_name): '''Returns data for infinite choice field''' data = [] if not request.is_ajax(): raise Http404 model = get_model(app_name, model_name) if 'term' in request.GET: term = request.GET['term'] page_limit = request.GET['page_limit'] data = model.objects.filter(title__startswith=term)[:int(page_limit)] json_data = json.dumps([{"id": item.id, "text": unicode(item.title)} for item in data]) if 'ids' in request.GET: id_list = request.GET['ids'].split(',') items = model.objects.filter(pk__in=id_list) json_data = json.dumps([{"id": item.id, "text": item.title} for item in items]) response = HttpResponse(json_data, content_type="application/json") response['Cache-Control'] = 'max-age=86400' return response
Django.db.models.get_model рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдореЙрдбрд▓ рд╡рд░реНрдЧ рджреЗрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдиреБрд░реЛрдз рдЪрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдпрд╛ рддреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ рд╡реЗрд░рд┐рдПрдВрдЯ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рд╡реЗрд░рд┐рдПрдВрдЯ, рдЬреЛ рдЖрдИрдбреА рд╡реЗрд░рд┐рдПрдмрд▓ рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рдЖрдИрдбреА рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрддреЗ рд╣реИрдВ, рдореЙрдбрд▓ рд╕реЗ рдЪреБрдиреЗ рдЬрд╛рддреЗ рд╣реИрдВред рджреВрд╕рд░рд╛ рдорд╛рдорд▓рд╛ рддрдм рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдкреНрд▓рдЧрдЗрди рдкрд╣рд▓реЗ рд╕реЗ рджрд░реНрдЬ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдЖрд░рдВрднреАрдХреГрдд рд╣реЛрддрд╛ рд╣реИред
рдореИрдВрдиреЗ рдХреИрд╢-рдХрдВрдЯреНрд░реЛрд▓ рд╣реЗрдбрд░ рдХреЛ рдПрдХ рджрд┐рди рдХреЗ рдХреИрд╢реЗ рдбреЗрдЯрд╛ рдЬреАрд╡рдирдХрд╛рд▓ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЬреЛрдбрд╝рд╛ред рдпрд╣ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреНрд╡реЗрд░реА рдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдЦреАрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рд╣реИред KLADR / FIAS рдЬреИрд╕реА рд╡рд┐рд╢рд╛рд▓ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рд╡рд╛рд▓реЗ рдлрд╝реАрд▓реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдкрд░ рдпрд╣ рдмрд╣реБрдд рдорджрдж рдХрд░рддрд╛ рд╣реИред
рдФрд░ рдпрд╣ рдХреИрд╕реЗ urls.py рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рд╣рдорд╛рд░реЗ рд╡рд┐рдЪрд╛рд░ рдХреЗ рд▓рд┐рдП рд▓рдЧ рд░рд╣рд╛ рд╣реИред
from django.conf.urls import patterns, url from views import infinite_choice_data urlpatterns = patterns('', url(r'^(?P<app_name>[\w\d_]+)/(?P<model_name>[\w\d_]+)/$', view=infinite_choice_data, name='infinite_choice_data'), )
рдлреЙрд░реНрдо рдлреАрд▓реНрдб
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, django рдореЗрдВ рдкреНрд░рдкрддреНрд░ рдлрд╝реАрд▓реНрдб рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдЗрд╕рдореЗрдВ рджрд░реНрдЬ рдХрд┐рдП рдЧрдП рдбреЗрдЯрд╛ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред рд╣рдорд╛рд░рд╛ рдХреНрд╖реЗрддреНрд░ рд╡рд░реНрдЧ рдРрд╕рд╛ рджрд┐рдЦреЗрдЧрд╛:
from django.forms import fields as f_fields from django.core.exceptions import ValidationError from django.core import validators from django.utils.translation import ugettext_lazy as _ class InfiniteChoiceField(f_fields.Field): '''Infinite choice field''' default_error_messages = { 'invalid_choice': _(u'Select a valid choice. %(value)s is not one of the available choices.'), } def __init__(self, data_model, multiple=False, disabled=False, widget_attrs=None, **kwargs): self.data_model = data_model self.disabled = disabled self.multiple = multiple widget = InfiniteChoiceWidget(data_model, multiple, disabled, widget_attrs) super(InfiniteChoiceField, self).__init__(widget=widget, **kwargs) def to_python(self, value): if value in validators.EMPTY_VALUES: return None if self.multiple: values = value.split(',') qs = self.data_model.objects.filter(pk__in=values) pks = set([i.pk for i in qs]) for val in values: if not int(val) in pks: raise ValidationError(self.error_messages['invalid_choice'] % {'value': val}) return qs else: try: return self.data_model.objects.get(pk=value) except self.data_model.DoesNotExists: raise ValidationError(self.error_messages['invalid_choice'] % {'value': value}) def prepare_value(self, value): if value is not None and hasattr(value, '__iter__') and self.multiple: return u','.join(unicode(v.pk) for v in value) return unicode(value.pk)
рдореБрдЭреЗ ModelMultipleChoiceField рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдирд╣реАрдВ рдорд┐рд▓рд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХреНрд╡реЗрд░реАрд╕реЗрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╣рдореЗрдВ рдореЙрдбрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рд╡рд┐рдЬреЗрдЯ рдХреЛ рдкрд╛рд░рд┐рдд рдореЙрдбрд▓, рдХрдИ рдФрд░ рдЕрдХреНрд╖рдо рдЭрдВрдбреЗ, рдФрд░ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЖрд░рдВрднреАрдХреГрдд рдХрд░рддрд╛ рд╣реИред
To_python рдкрджреНрдзрддрд┐ рдПрдХ рд╣реА рд▓рд╛рдЗрди рдкрд░ рдПрдХ рд╣реА id рдпрд╛ рдХрдИ id рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░рддреА рд╣реИ, рдЬрд┐рд╕реЗ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдПрдХрд╛рдзрд┐рдХ рдзреНрд╡рдЬ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИред рджреЛрдиреЛрдВ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдореЙрдбрд▓ рдореЗрдВ рдЪрдпрдирд┐рдд рдЖрдИрдбреА рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХреА рдЬрд╛рддреА рд╣реИред
рддреИрдпрд╛рд░реА_рд╡рд╛рдпреБ рд╡рд┐рдзрд┐ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдбреЗрдЯрд╛ рддреИрдпрд╛рд░ рдХрд░рддреА рд╣реИ: рдпрджрд┐ рдореЙрдбрд▓ рдХрд╛ рдПрдХ рднреА рдЙрджрд╛рд╣рд░рдг рдлрд╝реАрд▓реНрдб рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рдкрд╛рд╕ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХреА рдЖрдИрдбреА рд▓реМрдЯрд╛рддрд╛ рд╣реИ; рдпрджрд┐ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдпрд╛ рдХреНрд╡реЗрд░реАрд╕реЗрдЯ рдХреА рд╕реВрдЪреА рдкрд╛рд╕ рд╣реЛ рдЬрд╛рддреА рд╣реИ, рддреЛ рдЖрдИрдбреА рдХреЗ рд╕рд╛рде рдПрдХ рдкрдВрдХреНрддрд┐ рдХреЛ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд░ рджреЗрддрд╛ рд╣реИред
рдирд┐рд╖реНрдХрд░реНрд╖
рдореИрджрд╛рди рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред рдЖрд╡реЗрджрди
рдпрд╣рд╛рдВ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛
рд╣реИ ред рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ:
from django import forms from infinite_choice_field import InfiniteChoiceField from models import ChoiceModel class TestForm(forms.Form): choice = InfiniteChoiceField(ChoiceModel, multiple=True, disabled=False, required=False, initial=ChoiceModel.objects.filter(id__in=(7, 8, 12)))
рдЪреНрд╡рд╛рдЗрд╕рдореЙрдбрд▓ рдПрдХ рдордирдорд╛рдирд╛ рджреГрд╢реНрдп рдореЙрдбрд▓ рд╣реИ
class ChoiceModel(models.Model): title = models.CharField(max_length=100, verbose_name="Choice title") class Meta: verbose_name = 'ChoiceModel' verbose_name_plural = 'ChoiceModels' def __unicode__(self): return self.title
рдпрд╣ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╛рдж рд░рдЦрдирд╛ рдмрд╛рдХреА рд╣реИ,
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'infinite_choice_field', ... }
рдЖрдпрд╛рдд рдпреВрдЖрд░рдПрд▓
urlpatterns = patterns('',
рдФрд░ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдлреЙрд░реНрдо рдХреЗ рд╕реНрдЯреИрдЯрд┐рдХреНрд╕ рдХреЛ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ
<!doctype html> <html> <head> <title>Test InfiniteChoiceField</title> {{test_form.media}} </head> <body> <form action=""> {{test_form}} </form> </body> </html>