dispatch() yoxud View middleware

dispatch() yoxud View middleware

Muroali Narzullaev

telegram: 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?

  1. Brauzer foydalanuvchi tomonidan URL ga so‘rov yuboradi.
  2. Django sizning view klassingizni chaqiradi.
  3. View klassingizdagi dispatch() metodi ishlaydi.
  4. So‘rov turini tekshiradi: GET, POST, PUT, DELETE, ... So‘rov turiga qarab mos metodni (get(), post(), ...) chaqiradi.
  5. 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() GET deb aniqlaydi va get() 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:

  • request ustida 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.



Report Page