日期篩選

Python + django + 騰訊api 取得中國省市區列表

沒有留言
由於最近在建置關於中國物流方面的東西

講到物流一定會想到中國非常非常多的省市區

如果用手動新增的情況下你一定會發瘋

所以寫了一個可以自動抓省市區並新增至資料庫的程式

設計架構:

由於中國有分省跟市跟區

不過市有分直轄市跟一般的市

所以在結構上會有一些不一致

比如說

provinces 省

下面有

city 市

在更下面就是

district 區

而資料庫的關聯應該就是

省 關聯 市 關聯 區

不過當直轄市出現的時候

若把它當作省放的話

就會變成

provinces 省

關聯

city 市

不過拿上海市來說好了

上海市下面就已經是區了

這樣table跟資料概念不一

所以我的解決方法是

把直轄市仍放在city當中

並加一個Boolean判斷是否是直轄市

table架構如下
//uq_id指的是各省市區都有一個id
class ChinaProvinces(models.Model):

    name = models.CharField(

        pgettext_lazy('china provinces', 'name'),

    max_length=12)

    uq_id = models.CharField(

        pgettext_lazy('china provinces', 'uq_id'),

    max_length=6, unique=True)

    enable = models.BooleanField(default="True")

    sort = models.SmallIntegerField('sort', default=0)



    def __str__(self):

        return self.name



class ChinaCity(models.Model):

    //由於前面提到的直轄市並不隸屬於任何省,所以要設定null=True

    province = models.ForeignKey(

        ChinaProvinces, related_name='province', blank=True, null=True)

    name = models.CharField(

        pgettext_lazy('china city', 'name'),

    max_length=12)

    uq_id = models.CharField(

        pgettext_lazy('china city', 'uq_id'),

    max_length=6, unique=True)

    enable = models.BooleanField(default="True")

    is_municipality = models.BooleanField(default=False)

    sort = models.SmallIntegerField('sort', default=0)



    def __str__(self):

        return self.name



class ChinaDistrict(models.Model):

    city = models.ForeignKey(

        ChinaCity, related_name='city',)

    name = models.CharField(

        pgettext_lazy('china district', 'name'),

    max_length=12)

    uq_id = models.CharField(

        pgettext_lazy('china district', 'uq_id'),

    max_length=6, unique=True)

    enable = models.BooleanField(default="True")

    sort = models.SmallIntegerField('sort', default=0)



    def __str__(self):

        return self.name



接下來是如何跟騰訊call api取得我們要的資料

首先

先去註冊個QQ帳號吧

註冊完之後去申請金鑰


我們這次要使用的是騰訊web service api (beta)

寫這篇文章的時候他還是beta版

所以之後規格會不會改我不能跟大家保證

他的api route是


http://apis.map.qq.com/ws/district/v1 之後則是參數囉 首先是所有地區的列表
http://apis.map.qq.com/ws/district/v1/list?key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77
key後面的那一串就是剛剛申請的金鑰字串 打下來這一包的結構如


可以看到result下面有3筆list
照順序來說是
省.直轄市 市 區接下來就是針對某一個地區的id取

的該地區下一層級的地區列表
http://apis.map.qq.com/ws/district/v1/getchildren? &id=110000& key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77
id這個參數帶的就是地區代表碼

這包的結構如下:











實作
先在後台新增我想要自動匯入的省份或直轄市

views.py
import requests



QQ_KEY = "YOUR_KEY"



URL = "http://apis.map.qq.com/ws/district/v1/"

def import_address(request):



    def get_district(id):

        url = URL + "getchildren?&id=%s&key=%s" % (id, QQ_KEY,)

        response = json.loads(requests.get(url=url).text)

        return response



    def auto_create_from_provinces():

        provinces = ChinaProvinces.objects.filter(enable=True).all()

        try:

            for province in provinces:

                provinces_uq_id = province.uq_id

                cities = get_district(provinces_uq_id)

                for city in cities['result'][0]:

                    city_uq_id = city["id"]

                    city_name = city["fullname"]

                    new_city = ChinaCity(name=city_name, uq_id=city_uq_id, province=province)

                    new_city.save()

                    districts = get_district(city_uq_id)

                    for district in districts['result'][0]:

                        district_uq_id = district["id"]

                        district_name = district["fullname"]

                        new_district = ChinaDistrict(name=district_name, uq_id=district_uq_id, city=new_city)

                        new_district.save()

        except Exception as e:

            print(e)



    def auto_create_from_municipalities():

        municipalities = ChinaCity.objects.filter(enable=True, is_municipality=True).all()

        for municipality in municipalities:

            municipality_uq_id = municipality.uq_id

            districts = get_district(municipality_uq_id)

            for district in districts['result'][0]:

                district_uq_id = district["id"]

                district_name = district["fullname"]

                new_district = ChinaDistrict(name=district_name, uq_id=district_uq_id, city=municipality)

                new_district.save()



    auto_create_from_provinces()

    auto_create_from_municipalities()



    return HttpResponse("Done!!")



大功告成

沒有留言 :

張貼留言

技術提供:Blogger.

Pages

FACEBOOK