Django рдХреЗ рд▓рд┐рдП рд╢рд╣рд░ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдПрдХ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди

"рдПрдХ рдФрд░ - рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдХреБрдЫ рдпрд╛рдж рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдореЗрд░реЗ рд▓рд┐рдП" рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдПрдХ рдЕрдЪреНрдЫрд╛, рд▓реЗрдХрд┐рди рдЕрдЬреНрдЮрд╛рдд рд╕рдорд╛рдзрд╛рди рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣рд╛рдБ рдореЗрд░рд╛ рдиреБрд╕реНрдЦрд╛ рд╣реИ:



рдбреЗрдЯрд╛


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕рд╡рд╛рд▓ рдЦрдбрд╝рд╛ рд╣реБрдЖ - рд╢рд╣рд░реЛрдВ рдХреА рд╕реВрдЪреА рдХрд╣рд╛рдВ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рдРрддрд┐рд╣рд╛рд╕рд┐рдХ рд░реВрдк рд╕реЗ, рдореИрдВрдиреЗ рдПрдХ рд░рдЪрдирд╛рддреНрдордХ рдХреЙрдордиреНрд╕ рд▓рд╛рдЗрд╕реЗрдВрд╕ рдХреЗ рд╕рд╛рде geonames.org рдХрд╛ рд╡рд┐рдХрд▓реНрдк рдЪреБрдирд╛ред OpenStreetMaps рдиреЗ рдЗрд╕реЗ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рджрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ Google рд╕реЗ рд╕рдВрднрд╛рд╡рд┐рдд "рдкреЗрдЯреЗрдВрдЯ" рджрд╛рд╡реЗ, рдЬрд╣рд╛рдВ рдЬрд┐рдпреЛрдирд╛рдо рдбреЗрдЯрд╛ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд▓реЗрддрд╛ рд╣реИред (рд╣рд╛рд▓рд╛рдВрдХрд┐, http://www.openstreetmap.org/ рдкрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕реВрдЪрдирд╛ рдХреЗ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕реНрд░реЛрдд рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред)

рд╣рд┐рддреЛрдВ рдХреА рд╕рддрд╣реАрддрд╛ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдкрдХреЛ рдмрд╕ рдПрдХ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╢рд╣рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА, рдмрд┐рдирд╛ рднреВ-рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдЬреИрд╕реЗ рдХрд┐ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреА рдЦреЛрдЬ рдХрд░рдирд╛, рдЖрджрд┐), рдЖрдкрдХреЛ рднреВрдирд╛рдо рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рд╕рд░рд▓ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рд╕реВрдЯ рдХрд░рддрд╛ рд╣реИред
рдореИрдВрдиреЗ рдПрдХ рд╕реБрдВрджрд░ рд╕рдорд╛рдзрд╛рди рдЦреЛрдЬрдиреЗ рдореЗрдВ рд╕рдордп рдмрд░реНрдмрд╛рдж рдирд╣реАрдВ рдХрд┐рдпрд╛ рдФрд░ рдмрд╕ рд╕рдм рдХреБрдЫ рдХрд┐рдпрд╛, SQL рдФрд░ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП:

1. рдПрдХ рдЬрд┐рдпреЛрдиреЗрдо рдбреЗрдЯрд╛рдмреЗрд╕ рдмрдирд╛рдПрдВ рдФрд░ рд╡рд╣рд╛рдВ рдбреЗрдЯрд╛ рдЖрдпрд╛рдд рдХрд░реЗрдВ ( http://forum.geonames.org/gforum/posts/list/732.page )
рдЖрдк рдЗрд╕реЗ рд░реЛрдХ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЗрд╕ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреЗ рддрд░реНрдХ рдХреЗ рдЕрдзреАрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
2. рдХрдиреНрд╡рд░реНрдЯред рдореИрдВ рдХреЗрд╡рд▓ рд╕рд╣реА рд╕рдорд╛рдзрд╛рди рд╣реЛрдиреЗ рдХрд╛ рдвреЛрдВрдЧ рдирд╣реАрдВ рдХрд░рддрд╛, рдореИрдВ рдХреБрдЫ рдРрд╕реЗ рджреЗрд╢реЛрдВ рдХреЛ рдХрд╛рдЯрддрд╛ рд╣реВрдБ рдЬреЛ рддрдХрдиреАрдХреА рдореБрджреНрджреЗ рдЙрдард╛рддреЗ рд╣реИрдВ:

-- Country import insert into common_country(id,name,code,population,latitude,longitude,alternatenames) select geonameid as id,name,country as code, population,latitude,longitude,alternatenames from geonames.geoname gn where (gn.fcode IN ('PCLI','PCLIX','PCLD','PCLS','PCLF','PCL','TERR')); delete from common_country where id in (2077507,2170371,7910334,7909807); create unique index common_country_idx on common_country (id); create index common_country_code_idx on common_country(code); -- South Korea Fix update common_country set alternatenames = concat(alternatenames,"Korea, Republic of") where id = 1835841; -- City import insert into common_city(id,name,country_id,alternatenames,latitude,longitude, adm) select gn.geonameid as id, gn.name, c.id as country_id, gn.alternatenames, gn.latitude, gn.longitude, admin1 as adm from geonames.geoname gn left join common_country as c on gn.country=c.code where (gn.fcode in ('PPL','PPLC','PPLA','PPLA2','PPLA3','PPLA4')); 


рд╕реНрдкрд╖реНрдЯ рдорд╛рдЗрдирд╕ рдХреЛ рдбреЗрдЯрд╛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЬреЛ рд╕рдорд╛рдзрд╛рди рдкрд╛рдпрд╛ рд╡рд╣ PostgreSQL рдХреЗ рддрд╣рдд рд╕рдореНрдорд╛рдирд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдЦреЛрдЬ рдЙрдкрдХрд░рдг



рджреЗрд╢реА рдкреВрд░реНрдг-рдкрд╛рда MySQL рдЦреЛрдЬ рдЗрддрдиреЗ рд╕рд╛рд░реЗ рдмрд╕реНрддрд┐рдпреЛрдВ рдкрд░ рддреНрд╡рд░рд┐рдд рдЦреЛрдЬ рдХрд╛ рд╕рд╛рдордирд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреА рдереА, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рд╕реНрдлрд┐рдВрдХреНрд╕рд╕рд░реНрдЪ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ (рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреЛрдИ рдЕрдиреНрдп рд╕реЛрд▓рд░ рдХрд░реЗрдЧрд╛)
рд╕реВрдЪрдХрд╛рдВрдХ рдФрд░ рд╕реНрд░реЛрдд рд╡рд┐рдиреНрдпрд╛рд╕:

 source geo_city { type = mysql sql_host = localhost sql_user = citylist sql_pass = citylist sql_db = citylist sql_port = sql_query_pre = SET NAMES utf8 sql_query_post = sql_query = \ SELECT id, name, country_id, alternatenames, latitude, longitude\ FROM geo_city sql_query_info = SELECT * FROM `geo_city` WHERE `id` = $id # ForeignKey's sql_attr_uint = country_id } index common_city { source = geo_city path = /var/lib/sphinxsearch/data/geo_city docinfo = extern morphology = none stopwords = min_word_len = 2 charset_type = utf-8 min_prefix_len = 2 min_infix_len = 0 prefix_fields = name, alternatenames enable_star = 1 } 


рд╡рд┐рдЪрд╛рд░



рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:
Django рдХреЗ рдЪрдпрди
Django-рд╕реНрдлрд┐рдВрдХреНрд╕
django- рдкреНрд░реЛрдлрд╛рдЗрд▓ - рдПрдХ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдореЗрд░реЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП

рд╣рдо рджреЛрдиреЛрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбрд╛рд▓рддреЗ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ INSTALLED_APPS рдореЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред
Django-sphinx рдХреЛ settings.py рдореЗрдВ API рд╕рдВрд╕реНрдХрд░рдг рд╕рдВрдЦреНрдпрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ

рд╕реНрдлрд┐рдВрдХреНрд╕ 0.9.9 рдХреЗ рд▓рд┐рдП:
 SPHINX_API_VERSION = 0x116 


рднреВ-рддрд░реНрдХ / рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╢рд╣рд░ рдФрд░ рджреЗрд╢ рдХреЗ рд▓рд┐рдП рдПрдХ рдореЙрдбрд▓ рдмрдирд╛рдПрдВ
(рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рднреВ)

 class Country(models.Model): name = models.CharField(max_length=200) code = models.CharField(max_length=10) population = models.IntegerField() latitude = models.FloatField() longitude = models.FloatField() alternatenames = models.CharField(max_length=2000, blank=True, default='') def __str__(self): return unicode(self.name).encode('utf-8') def __unicode__(self): return unicode(self.name) class City(models.Model): name = models.CharField(max_length=200) country = models.ForeignKey(Country) alternatenames = models.CharField(max_length=2000, blank=True, default='') latitude = models.FloatField(default=0) longitude = models.FloatField(default=0) adm = models.CharField(max_length=200) search = SphinxSearch(weights={ 'name': 100, 'alternatenames': 80 }) def __str__(self): return unicode(self.name).encode('utf-8') def __unicode__(self): return unicode(self.name) 


рдпрджрд┐ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рд╢рд╣рд░ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рдФрд░ рдЙрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдореЙрдбрд▓ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬреЛ рдкреНрд░реЛрдлрд╛рдЗрд▓ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ, рдореЗрд░реЗ рдкрд╛рд╕ рдпрд╣ рдЙрдкрдпреЛрдЧ рд╣реИ:

 class CustomUserProfile(models.Model): user = models.ForeignKey(User, unique=True) full_name = models.CharField(max_length=200, blank=True) city = models.ForeignKey(City, blank=True, null=True) country = models.ForeignKey(Country, blank=True, null=True, editable=False) date_registered = models.DateField(editable=False, auto_now_add=True) 


рдФрд░ рдкреНрд░реЛрдлрд╛рдЗрд▓ рдлреЙрд░реНрдо:

 class UserProfileForm(forms.ModelForm): ''' Form to edit profile''' full_name = forms.CharField(widget=forms.TextInput()) city = selectable.AutoCompleteSelectField( label='City please', lookup_class = common.lookups.CityLookup, required=False, ) def clean_city(self): """ Convert city code to city object """ city_id = int(self.data["city_1"].encode("utf8")) city = City.objects.get(id=city_id) return city class Meta: model = CustomUserProfile exclude = ("user",) 


рдФрд░ рд╕реЗрдЯрд┐рдВрдЧ рдореЗрдВ

 AUTH_PROFILE_MODULE = 'usermanage.CustomUserProfile' 


рдпрд╣рд╛рдБ django- рдкреНрд░реЛрдлрд╛рдЗрд▓ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдЕрдзрд┐рдХ

django-selectable рдХреЛ urls.py рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ

 (r'^selectable/', include('selectable.urls')), 


рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдХреНрд╡реЗрд░реАрдЬрд╝ рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдиреЗ рдФрд░ рдлрд╝реАрд▓реНрдб рдХреЛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд░реВрдк рд╕реЗ рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реБрдХрдЕрдк рдФрд░ рдЙрд╕рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдБ:

 class CityLookup(LookupBase): model = City item = None def get_query(self, request, term): qs = self.model.search.query(term + "*") return qs def get_queryset(self): return None def get_item_id(self, item): return item.id def get_item_value(self, item): if (not self.item): return smart_unicode(item) return smart_unicode(self.item.name) def get_item_label(self, item): return u"%s, %s" % (item.name, item.country) def get_item(self, value): item = None if value: try: item = City.objects.get(id=value) self.item = item except IndexError: pass return item try: registry.register(CityLookup) except: pass 


рдЖрдкрдХреЛ рд░реВрдк- рд░реЗрдЦрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд▓реБрдХрдЕрдк рдФрд░ рдЪрдпрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдлрд╝реАрд▓реНрдб / рд╡рд┐рдЬреЗрдЯ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ

 import selectable.forms as selectable import geo.lookups</code> 

Django- рдЪрдпрдиреАрдп рдХреЛ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП jquery рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, jquery рдФрд░ jquery-ui (jquery.dj.selectable.js - django-selectable рдХреЛ рдЬрд╛рддрд╛ рд╣реИ) рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЙрдиреНрд╣реЗрдВ рдЖрдзрд╛рд░ рд╕реЗ рдЬреЛрдбрд╝реЗрдВред
 <script type="text/javascript" src="/js/jquery/jquery.min.js"></script> <script type="text/javascript" src="/js/jquery/jquery-ui.min.js"></script> <script type="text/javascript" src="/js/jquery/jquery.dj.selectable.js"></script> 


рдЕрдЧрд░ рд╕рдм рдХреБрдЫ рдареАрдХ рд░рд╣рд╛, рддреЛ рдЖрдЙрдЯрдкреБрдЯ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛:



рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдРрд╕реЗ (рд╡реИрдХрд▓реНрдкрд┐рдХ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдирд╛рдо рдХреЗ рд░реВрдкрд╛рдВрддрд░ рд╣реЛрддреЗ рд╣реИрдВ)



рдПрдХ рддрд╛рд░реНрдХрд┐рдХ рдирд┐рд░рдВрддрд░рддрд╛, рдореИрдВ рдПрдХ рд╣реА рдирд╛рдо рдХреЗ рд╕рд╛рде рдмрд╕реНрддрд┐рдпреЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП admin1 (рдкрд╣рд▓реЗ рд╕реНрддрд░ рдХреА рдПрдХ рдкреНрд░рд╢рд╛рд╕рдирд┐рдХ рдЗрдХрд╛рдИ) рдХреЗ рдЕрд▓рд╛рд╡рд╛ рджреЗрдЦрддрд╛ рд╣реВрдВ, рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рдФрд░ рдкреБрди: рдкреНрд░рдпреЛрдЬреНрдп рдЖрд╡реЗрджрди рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЗрдореЗрдЯрд░ рдкрд░реАрдХреНрд╖рдг, MySQL рдореЗрдВ рдХрдо рд╕реЗ рдХрдо django-geonames рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдЦрд┐рд░реА Kyiv.py рдореИрдВ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рд░реВрдк рд╕реЗ рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рдЕрдм рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рд░рд╛рд╕реНрддрд╛ рдЬрд┐рдпреЛрдбреНрдЬреИрдВрдЧреЛ, рдкреЛрд╕реНрдЯрдЧреНрд░реЗрд╕реАрдХреНрдпреВ рдФрд░ рдкреЛрд╕реНрдЯрдЬреАрдЖрдИрдПрд╕ рдХреА рджрд┐рд╢рд╛ рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╢рд╣рд░ рдХреА рднреВрдорд┐рдХрд╛ рд╕рд┐рд░реНрдл рд╕реВрдЪрдирд╛рддреНрдордХ рд╣реЛрдиреЗ рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛ рд░рд╣реА рд╣реИред

рдкреБрдирд╢реНрдЪ рдЕрдЧрд░ рдХрд┐рд╕реА рдХреЛ рдЯреЗрд╕реНрдЯ рдбреЗрдореЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реИ, рддреЛ рдореИрдВ рдЗрд╕реЗ рдкреЛрд╕реНрдЯ рдХрд░реВрдВрдЧрд╛ред

рд╕рдВрджрд░реНрдн:
рд╕рдВрднрд╛рд╡рд┐рдд OSM рдбреЗрдЯрд╛ рд╕реНрд░реЛрддреЛрдВ рдХреА рд╕реВрдЪреА

github рдФрд░ bitbucket рдкреГрд╖реНрда рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВред

рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

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


All Articles