GeoIPとDjango

Web開発者は多くの場合、IPアドレスでユーザーを見つけるという古典的なタスクに直面しています。 たとえば、世界のMaxmind GeoliteベースまたはロシアのIpgeoBaseに基づいたさまざまなソリューションがあります。 それらはすべて、かなり低レベルのAPIを持っています。これは理解できます。入り口にはIPアドレスがあり、出口には国または都市があり、運がよければ、他の有用な情報もあります。



立ち上げたGeoIPを備えたすべてのサイトには共通の機能があります。単純な位置情報が必要なだけでなく、ユーザーの場所に応じてサイトに異なるコンテンツを表示する必要もあります。 このタスクを簡単にするために、django-ipgeobaseアプリケーションに触発された小さなdjango-geoipバッテリーを作成しました。





ジャンゴ・ジオップ



このアプリケーションの主な利点は、ユーザーの地理を自動的に判別し、それを要求オブジェクトに渡すことができることです。 これで、「地域性」を持つサイトのコンテンツは、request.locationの値によってviews.pyで簡単にフィルタリングできます。



特徴




実装機能

django-geoipアプリケーションは、国-地域-都市という地理的階層をサポートします。これは、DBMSに正規化された形式で保存されます。 4番目の表には、地理のすべての要素へのリンクを持つIPアドレスの範囲に関するデータがあります。 現在のバージョンはipgeobase.ruデータでのみ動作し、ロシアとウクライナのほぼ1000の都市と15万のIP範囲です。



データベースにデータを保存する理由の1つは、ビジネスロジックの課題を満たす独自の地理モデルを作成する必要があることです。 たとえば、あるプロジェクトでは、ユーザーの場所の定義をロシアの地域に限定し、別のプロジェクトでは、会社が存在する一連の都市に限定します。 このモデルは、ipgeobase地理階層の「ファサード」パターンを実装するため、自分で地理位置情報を柔軟に構成できます。



私たちのサイトにはいくつかの地域的な「バージョン」があり、それぞれに独自のコンテンツが含まれていると想像してください。 この場合、地域には任意の名前を付けることができ、たとえば、ロシア連邦のいくつかの地域(図のgeo_locationテーブル)を含めることができます。



これがどのように構成され動作するかの例を次に示します。 地理モデルMyCustomLocationを定義します。



# geo/models.py class MyCustomLocation(GeoLocationFacade): name = models.CharField(max_length=100) region = models.OneToOneField(Region, related_name='my_custom_location') is_default = models.BooleanField(default=False) @classmethod def get_by_ip_range(cls, ip_range): """     IP-.       , ,   ,       """ return ip_range.region.geo_location @classmethod def get_default_location(cls): """  -,  ,       IP""" return cls.objects.get(is_default=True) @classmethod def get_available_locations(cls): return cls.objects.all() class Meta: db_table = 'geo_location'
      
      





これは通常のジャンゴモデルで、GeoIPファサードの「インターフェイス」を実装する3つのクラスメソッドによって補完されます。 各関数の目的は、名前とドックストリングから明らかです。 データベースに都市の名前を入力し、それらをdjagno-geoipモデルにバインドします。



settings.pyに書き込みます:

 GEOIP_LOCATION_MODEL = 'geo.models.MyCustomLocation'
      
      





ミドルウェアを追加して、地域を自動的に検出します。

 MIDDLEWARE_CLASSES = (... 'django_geoip.middleware.LocationMiddleware', ... )
      
      





そして出来事:request.locationには、各ユーザーのMyCustomLocationモデルの値が含まれるようになりました。

 def my_view(request): """ Passing location into template """ ... context['location'] = request.location ...
      
      





ユーザーがこれらの都市のいずれにも属していない場合、デフォルトの地域(get_default_location)が割り当てられます。



このアプローチにより、ユーザーの場所に応じてコンテンツが互いに異なる「地域」サイトを作成するタスクが大幅に容易になります。



次は何ですか



このアプリケーションはアルファ版ですが、本番環境(バージョン0.2.2)ではうまく機能します。 アルファステータスは、APIが将来変更されることを示唆しています。 私たちは、ロシアだけでなく世界の地域の定義を実行することを含め、それをさらに維持し、発展させることを計画してい ますデータベース内の適切なIP範囲の検索を最適化するというアイデアも興味深いように思えました。



ソースコードはgithubで入手でき、コメントを待っています。



All Articles