рдореЗрд░рд╛ рд╡рд┐рдХрд▓реНрдк рдорд▓реНрдЯреАрдкрд▓ рдЗрдиреНрдкреБрдЯ + рдСрдЯреЛрдХрдореНрдкреНрд▓реАрдЯ рд╣реИ

рд╢реБрд░реБрдЖрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЖрдЧрд╛рдореА рдЫреБрдЯреНрдЯрд┐рдпреЛрдВ рдкрд░ рд╕рднреА рдХреЛ рдмрдзрд╛рдИ рджреЗрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛!

рдФрд░ рдЕрдм рдореЗрд░реА рдХрд╣рд╛рдиреА рдХрд╛ рд╕рд╛рд░ред

рдХреБрдЫ рд╣рдлреНрддреЗ рдкрд╣рд▓реЗ рдореБрдЭреЗ django рдореЗрдВ рдбреНрд░реЙрдкрдбрд╛рдЙрди рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред рдЬреИрд╕реЗ рд╣реА рдЖрдк рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╣реИрдВ рдорд╛рди рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд▓реЛрдб рдХрд┐рдП рдЬрд╛рдиреЗ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕реВрдЪреА рд╕реЗ рдПрдХ рдорд╛рди рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдФрд░ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдкрд╣рд▓реЗ, рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рд╣рдо рдХрд┐рд╕ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВ:



рддреЛ, рдореЙрдбрд▓ рдХреЗ рд╕рд╛рде рдлрд╛рдЗрд▓ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдмрд╕ рджреЛ рдореЙрдбрд▓ рдмрдирд╛рдП рдФрд░ рдЙрдиреНрд╣реЗрдВ рдХрдИToManyField рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд┐рдВрдХ рдХрд┐рдпрд╛ред

models.py

from django.db import models class City(models.Model): name = models.CharField(max_length=150, unique=True) class Country(models.Model): name = models.CharField(max_length=100) cities = models.ManyToManyField(City, blank=True) 

рдлрд┐рд░ рдореИрдВ рдорд╛рдирдХ рд╡рд┐рдЧреЗрдЯреНрд╕ рд╕реАрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЪрдврд╝ рдЧрдпрд╛ред рдорд▓реНрдЯреАрд╣реИрдбрдЗрдирдкреНрдпреВрдЯ рд╕рдмрд╕реЗ рдЙрдкрдпреБрдХреНрдд рдирд┐рдХрд▓рд╛, рд▓реЗрдХрд┐рди рдпрд╣ рд╣рд┐рдбрдирдЗрдВрдкреБрдЯ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдерд╛ рдФрд░ рдЕрдм рддрдХ рдЗрд╕рдХрд╛ рдХреЛрдИ рд╕реНрд╡рдд: рдкреВрд░реНрдг рдХрд╛рд░реНрдп рдирд╣реАрдВ рдерд╛ред рдлрд╝рд╛рдЗрд▓> рдирдпрд╛ рдЪрд▓реЛред

widget.py

 from django.forms.util import flatatt from django.utils.datastructures import MultiValueDict, MergeDict from django.utils.encoding import force_unicode class MultipleInput(Input): input_type = 'text' def __init__(self, attrs=None, choices=()): super(MultipleInput, self).__init__(attrs) self.choices = choices def render(self, name, value, attrs=None, choices=()): if value is None: value = [] final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) id_ = final_attrs.get('id', None) inputs = [] for i, v in enumerate(value): input_attrs = dict(value=force_unicode(v), **final_attrs) if id_: input_attrs['id'] = '%s_%s' % (id_, i) inputs.append(u'<p><input%s /><a href="#" id="remove_%s">Remove</a></p>' % (flatatt(input_attrs), id_)) return mark_safe(u'\n'.join(inputs)) def value_from_datadict(self, data, files, name): if isinstance(data, (MultiValueDict, MergeDict)): return data.getlist(name) return data.get(name, None) 

рдореИрдВрдиреЗ рдХреНрдпрд╛ рдХрд┐рдпрд╛? рдореИрдВрдиреЗ рдорд╛рдирдХ MultipleHiddenInput рд▓рд┐рдпрд╛, рдЗрд╕реЗ рдЗрдирдкреБрдЯ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдФрд░ рдЗрдирдкреБрдЯреНрд╕рдПрдкреЗрдВрдб рдмрджрд▓ рджрд┐рдпрд╛ред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓рдЧрднрдЧ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрджрд▓рд╛ рд╣реИред Inputs.append рдореЗрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдУрд░ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ HTML рдХреЛрдбред рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдХреНрдпреЛрдВ рд╣реИ, рдпрд╣ рдиреАрдЪреЗ рд╕рдордЭрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рдореИрдВ рдкреНрд░рдкрддреНрд░реЛрдВ рдХреА рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ред

рдЕрдм рд░реВрдкред рд╢рд╣рд░реЛрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП, рдкрд╣рд▓реЗ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдПрдХрд╛рдзрд┐рдХInput рд╡рд┐рдЬреЗрдЯ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВред рд╕рд╛рде рд╣реА рд╡рд┐рдЬреЗрдЯ рдкрд░ рдЖрдк рд╡рд┐рд╢реЗрд╖рддрд╛ 'рд╡рд░реНрдЧ' рдХреЛ рдорд╛рди 'рд╕реНрд╡рддрдГ рдкреВрд░реНрдгрддрд╛' рдХреЗ рд╕рд╛рде рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирд╛рдо рд╕реЗ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдпрд╣ рднрд╡рд┐рд╖реНрдп рдХреЗ рд╕реНрд╡рдд: рдкреВрд░реНрдг рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред
ManyToManyField рдмрдВрдбрд▓ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдХрд╛рд░рдг, __init__ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдкреНрд░рдкрддреНрд░ рдкрд░ рджрд┐рдЦрд╛рдИ рджреАред рдпрд╣рд╛рдВ рд╣рдо рддрддреНрд╡реЛрдВ рдХреЗ рдХреНрд░рдо рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╣рдЯрд╛рддреЗ рд╣реИрдВред
рдпрджрд┐ рдкреНрд░рдкрддреНрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдпрд╣ рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рд╣реИ рдХрд┐ __init__ рд╣рдорд╛рд░реА рдорджрдж рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рд╢рд╣рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рднреА рдореВрд▓реНрдпреЛрдВ рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╡рд╛рдкрд╕ рднреЗрдЬрддрд╛ рд╣реИред

forms.py

 from django import forms from myapp.widget import MultipleInput class CreateCountryForm(forms.Form): name = forms.CharField(widget=forms.TextInput(), required=True) cities = forms.CharField(widget=MultipleInput(attrs={'class' : 'autocompleteCity'}), required=False) def __init__(self, *args, **kwargs): super(CreateCountryForm, self).__init__(*args, **kwargs) s = kwargs.get('data', None) if s: cities = s.getlist('cities') for i in xrange(len(cities)-1, -1, -1): if cities.count(cities[i]) != 1: del cities[i] 

рдпрд╣ рд╣рдорд╛рд░реЗ рдореЙрдбрд▓реЛрдВ рдХреЛ рдареАрдХ рд╕реЗ рд╕рд╣реЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдореИрдкрд┐рдВрдЧ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИред рд╕рд╛рде рд╣реА рдСрдЯреЛ-рдкреВрд░реНрддрд┐ рдХреЗ рд▓рд┐рдП рдЕрдЬрд╛рдХреНрд╕ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреВрд╕рд░рд╛ рдорд╛рдирдЪрд┐рддреНрд░рдгред

views.py

 from django.shortcuts import render_to_response from django.http import HttpResponseRedirect from django.template import RequestContext from myapp.forms import CreateCountryForm from myapp.models import City def create_country(request, form_class=None, template_name='create_country.html'): form_class = CreateCountryForm if request.method == 'POST': form = form_class(data=request.POST, files=request.FILES) if form.is_valid(): obj = form.save(commit=False) obj.save() cities = request.POST.getlist('cities') obj.cities.clear() for c in cities: city, created = City.objects.get_or_create(c) obj.cities.add(city) return HttpResponseRedirect('index') else: form = form_class() context = { 'form': form, } return render_to_response(template_name, context, context_instance=RequestContext(request)) def city_autocomplete(request): try: cities = City.objects.filter(name__icontains=request.GET['q']).values_list('name', flat=True) except MultiValueDictKeyError: pass return HttpResponse('\n'.join(cities), mimetype='text/plain') 

рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдФрд░ рдкрд╛рдареНрдпрдХреНрд░рдо рдХреЗ url рд╡рд┐рдиреНрдпрд╛рд╕ред

urls.py

 from django.conf.urls.defaults import * from myapp import views urlpatterns = patterns('' url(r'^city_autocomplete/$', views.city_autocomplete, name='city_autocomplete'), url(r'^create_country/$', views.create_stream, name='stream_create_stream'), ) 

рд╣рдордиреЗ рд╕рднреА рд╕рдмрд╕реЗ рдХрдард┐рди рдХреЛ рдкрд╛рд░ рдХрд░ рд▓рд┐рдпрд╛, рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝реЗрдВред рдореИрдВрдиреЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд┐рд░рд╛рд╕рдд рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рд▓рд┐рдЦрд╛ рд╣реИ, рдмрд╕ рд╕рд╛рд░ рдХреЛ рдкреНрд░рддрд┐рдмрд┐рдВрдмрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдСрдЯреЛ- рдХрдореНрдкреНрд▓реАрдЯ рдХреЗ рд▓рд┐рдП рдЙрджрд╛рд╣рд░рдг jQueryAutocompletePlugin рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

create_country.html

 <!DOCTYPE html> <html lang="ru"> <head> <link type="text/css" href="https://github.com/agarzola/jQueryAutocompletePlugin/blob/master/jquery.autocomplete.css" media="all" rel="stylesheet" /> <script type="text/javascript" src="https://github.com/agarzola/jQueryAutocompletePlugin/blob/master/jquery.autocomplete.js"></script> <script type="text/javascript" src="{{ MEDIA_URL }}js/add_and_remove.js"></script> </head> <body> <form enctype="multipart/form-data" action="" method="post">{% csrf_token %} <label for="id_name"></label> {{ form.name }}</br> <a href="#" id="addCity"> </a> <div id="p_cities"> {{ form.cities }} </div> <script type="text/javascript"> jQuery().ready(function() { jQuery(".autocompleteCity").autocomplete("/city_autocomplete/", { multiple: false }); }); </script> <input class="button" type="submit" value=""/> </form> </body> </html> 

рдФрд░ рдкреВрд░реНрдгрддрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВ add_and_remove.js рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрддрд╛ рд╣реВрдВред

add_and_remove.js

 $(function() { var CitiesDiv = $('#p_cities'); var i = $('#p_cities p').size(); $('#addCity').live('click', function() { $('<p><input class="autocompleteCity ac_input" type="text" id="id_cities_' + i +'" size="20" name="cities" placeholder="Input Value" autocomplete="off" /><a href="#" id="remove_id_cities">Remove</a></p>').appendTo(CitiesDiv); $('#id_cities_' + i).focus(); i++; jQuery(".autocompleteCity").autocomplete("/city_autocomplete/", { multiple: false }); return false; }); $('#remove_id_cities').live('click', function() { if( i > 0 ) { $(this).parents('p').remove(); i--; } return false; }); }); 

PS рдпрд╣ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рд╕рд╛рдордирд╛ рдХреА рдЧрдИ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд┐рд░реНрдл рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИ, рдФрд░ рдпрд╣ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реЛрдиреЗ рдХрд╛ рджрд╛рд╡рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдореЙрдбрд▓ рдирд╛рдореЛрдВ рдХреЛ рдмреЗрддрд░рддреАрдм рдврдВрдЧ рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ; рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╕рд╛рдЗрдЯ рдкрд░ рдЯреИрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдЙрдкрдпреБрдХреНрдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдореИрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдФрд░ рд╕реБрдЭрд╛рд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЖрднрд╛рд░реА рд░рд╣реВрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдХреЗрд╡рд▓ 4 рдорд╣реАрдиреЗ рдХреЗ рд▓рд┐рдП рдбреЗрдВрдЧреВ рдФрд░ рдЕрдЬрдЧрд░ рд╕реЗ рдкреНрдпрд╛рд░ рд╣реИред

Source: https://habr.com/ru/post/In135263/


All Articles