dispatch() yoxud View middleware
Muroali Narzullaevtelegram: Software enginee(g)r
Django’dagi Class-Based View (CBV) larni ishlatganimizda, foydalanuvchidan keladigan so‘rovlar (request) dispatch() metodiga birinchi bo‘lib keladi.
Oddiy so‘z bilan aytganda:
dispatch() — bu "so‘rovni qaysi metod (get/post/put/delete) ishlashi kerakligini aniqlab beruvchi markaziy boshqaruv punkti".
dispatch() qanday ishlaydi?
- Brauzer foydalanuvchi tomonidan URL ga so‘rov yuboradi.
- Django sizning view klassingizni chaqiradi.
- View klassingizdagi
dispatch()metodi ishlaydi. - So‘rov turini tekshiradi: GET, POST, PUT, DELETE, ... So‘rov turiga qarab mos metodni (
get(),post(), ...) chaqiradi. - Natija foydalanuvchiga qaytariladi.
Quyidagi misolga etibor qarating:
from django.views import View
from django.http import HttpResponse
class HelloView(View):
def get(self, request, *args, **kwargs):
return HttpResponse("GET so'rovi uchun javob")
def post(self, request, *args, **kwargs):
return HttpResponse("POST so'rovi uchun javob")
Agar foydalanuvchi bu view'ga GET so‘rovi yuborsa:
- Django
dispatch()metodini chaqiradi. dispatch()GETdeb aniqlaydi vaget()metodini ishga tushiradi.
Agar POST bo‘lsa — post() ishlaydi.
dispatch() metodini o‘zgartirish (override) nima uchun kerak?
Siz dispatch() metodini "hook point" sifatida ishlatishingiz mumkin, ya’ni:
requestustida o‘zgartirish kiritish- Avtorizatsiya yoki tekshiruv kiritish
- Log yozish
- Maxsus istisnolarni ko‘rish
Masalan:
class MyView(View):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return HttpResponse("Kirish kerak!", status=403)
return super().dispatch(request, *args, **kwargs)
Bu holatda, barcha so‘rovlar dispatch() orqali filtrdan o‘tadi — foydalanuvchi tizimga kirmagan bo‘lsa, hech qaysi metod (get, post) ishlamaydi.
dispatch() ning strukturasi:
def dispatch(self, request, *args, **kwargs):
# bu yerda request ustida ishlov berish mumkin
return super().dispatch(request, *args, **kwargs)
request: foydalanuvchining HTTP so‘rovi*args, **kwargs: URL’dan yoki boshqa joydan kelgan qo‘shimcha argumentlar
View'ga so‘rov yuborilganida, foydalanuvchining IP manzilini log ga yozamiz (yoki faylga, yoki print qilamiz — test uchun).
dispatch() orqali IP manzilni olish va logga yozish
import logging
from django.views import View
from django.http import HttpResponse
# Django logging sistemasi uchun logger yaratamiz
logger = logging.getLogger(__name__)
class LogIPView(View):
def dispatch(self, request, *args, **kwargs):
# IP manzilni olish
ip = self.get_client_ip(request)
# IP manzilni logga yozish
logger.info(f"Foydalanuvchining IP manzili: {ip}")
# davomiy ishash uchun asosiy dispatch chaqiriladi
return super().dispatch(request, *args, **kwargs)
def get_client_ip(self, request):
"""Real IP manzilni olish (proxy ortida bo‘lsa ham)"""
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
def get(self, request, *args, **kwargs):
return HttpResponse("IP manzilingiz logga yozildi.")
Natija:
- Foydalanuvchi brauzer orqali bu view'ga murojaat qilsa:
dispatch()metodi ishga tushadi.- Foydalanuvchining IP manzili aniqlanadi.
logger.info(...)orqali logga yoziladi (odatda terminalga yoki faylga).- So‘ng
get()metod ishlaydi va javob qaytaradi.
Log tizimini sozlash (settings.py ichida):
Agar siz log yozishni faylga qilishni istasangiz, settings.py faylingizda quyidagilarni qo‘shing:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': 'logs/ip_log.txt',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'INFO',
'propagate': True,
},
},
}
Shunda logger.info(...) orqali yozilgan loglar logs/ip_log.txt faylida saqlanadi.