اذهب إلى المحتوى
  • 1

كيف أحصل على عنوان IP للمستخدم في جانغو Django؟

Amer Abdallah

السؤال

أنا أستخدم الكائن GeoIP لكي أحصل على عنوان IP الخاص بالمستخدم في ملف العرض view التالي:

from django.contrib.gis.utils import GeoIP
from django.shortcuts import render_to_response


def details(request):
  geoip = GeoIP()
  lat, long = geoip.lat_lon(request.META['REMOTE_ADDR'])
  return render_to_response('My_Details.html', locals())

لكن المشكلة أنه يظهر لي الخطأ التالي:

KeyError at /mypage/
    'REMOTE_ADDR'
    Request Method: GET
    Request URL:    http://localhost:8000/mypage/
    Django Version: 1.2.4
    Exception Type: KeyError
    Exception Value:    
    'REMOTE_ADDR'
    Exception Location: /mysite/details/views.py in home, line 9
    Python Executable:  /usr/bin/python
    Python Version: 2.7
    Python Path:    ['/mysite', '/usr/local/lib/python2.7/dist-packages/flup-1.0.2-py2.6.egg', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/pymodules/python2.7']
    Server time:    Thu, 2 Aug 2021 20:42:50 +0200

أعتقد أن الخطأ بسبب المفتاح REMOTE_ADDR، ولكن لا أعرف كيفية إصلاح هذا الخطأ.

أستخدم جانغو Django الإصدار 1.2.4 وبايثون 2.7

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 1

يمكنك أن تقوم بعمل دالة تقوم بإرجاع عنوان IP ، كالتالي:

def getClientIP(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    # في حالة وجود العنصر HTTP_X_FORWARDED_FOR سوف يحتوي على عنوان IP في بدايته
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

لاحظ كيف تم إستخدام التابع get حتى تحتدث مشكلة في حالة عدم وجود المفتاح REMOTE_ADDR (سوف يتم إرجاع None في هذه الحالة).

كما يجب أن تتأكد من إعدادات reverse proxy بشكل صحيح (إن وجد)، على سبيل المثال: تثبيت mod_rpaf  لخادم الويب Apache.

ملاحظة: يحتوي العنصر X-Forwarded-For على عنوان IP في بدايته في أغلب الأحيان، ولكن في أحيان أخرى مثل في خوادم Heroku يتم وضع عنوان IP في نهايته، أي أنك يجب أن تستخدم -1 بدلًا من 0، كالتالي:

def getClientIP(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    # في حالة وجود العنصر HTTP_X_FORWARDED_FOR سوف يحتوي على عنوان IP في بدايته
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[-1].strip()
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

الآن يمكنك أن تستعمل الدالة كالتالي:

client_ip = getClientIP(request)

كما يمكنك أن تستعمل حزمة جاهزة للحصول على عنوان IP مثل حزمة django-ipware، أولًا يجب تثبيتها من خلال أحد الطرق التالية:

1. easy_install django-ipware

2. pip install django-ipware

3. git clone http://github.com/un33k/django-ipware
    a. cd django-ipware
    b. run python setup.py install

4. wget https://github.com/un33k/django-ipware/zipball/master
    a. unzip the downloaded file
    b. cd into django-ipware-* directory
    c. run python setup.py install

ويتم إستعمال الحزمة كالتالي:

# في ملف عرض view أو middleware حيث يكون الكائن `request` متاحًا

from ipware import get_client_ip

ip, is_routable = get_client_ip(request)
if ip is None:
    # تعذر الحصول على عنوان IP الخاص بالعميل
    pass
else:
    # في حالة وجود عنوان IP
    print(ip)

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

إجابة سامح رائعة كالعادة.. وبالنسبة لإجابته الأولى أيضاً يمكننا أن نضيف تحسين عليها. بدلاً من أخذ أول IP في قائمة X_FORWARDED_FOR ، أخذ أول واحد ليس في عنوان IP داخلي معروف، حيث أن بعض أجهزة التوجيه لا تحترم البروتوكول، ويمكنك رؤية ips الداخلية باعتبارها القيمة الأولى في القائمة:

PRIVATE_IPS_PREFIX = ('10.', '172.', '192.', )

def get_client_ip(request):
	#request العميل من ال ip الحصول على  
    remote_address = request.META.get('REMOTE_ADDR')
    #None إذا كانت متوفرةوإلا   REMOTE_ADDR  لتكون  ip  تعيين القيمة الافتراضية للـ
    ip = remote_address
    #HTTP_X_FORWARDED_FOR من private ليس بروكسي وليس ip حاول الحصول على أول عنوان
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        proxies = x_forwarded_for.split(',')
        #الخاص  ips   إزالة ال
        while (len(proxies) > 0 and
                proxies[0].startswith(PRIVATE_IPS_PREFIX)):
            proxies.pop(0)
        #الأول الذي ليس خاصاً (من البروكسي)  ip أخذ عنوان
        if len(proxies) > 0:
            ip = proxies[0]
    return ip

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

أحياناً عند  التعامل مع proxies يعيدون أحياناً ip متعددة  في HTTP_X_FORWARDED_FOR ولذلك للحصول على ال ip الحقيقي سيكون آخر ip في ال list لذلك سينستخدم إجابة سامح مع تعديل بسيط كالتالي 

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[-1].strip()
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...