3

django源码阅读笔记

 2 years ago
source link: http://wwj718.github.io/post/%E6%8A%80%E6%9C%AF/django-source-code-explore-note/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

django源码阅读笔记

2016-03-07

Open edX的后端采用Django来写,Django是一个大而全的web框架,许多地方和Rails相似

Open edX对Django框架做了大量的改造,对其特性的应用也是十分全面。由于时常需要去hack Open edX,以至于不得不深入到Django源码本身,读别人的源码,和大多事情一样,都符合万事开头难的规律,深入之后,其乐无穷.

初极狭,才通人,复行数十步,豁然开朗

Open edX的最新稳定版所依赖的Django版本为1.8.7,所以我主要阅读的也是这个版本的源码:Django 1.8.7

下面下阅读过程一些值得记录的地方记下来

#django-admin 安装django后,我们会获得一个命令行工具django-admin,用于创建django项目和djangoapp

这主要是通过entry_points实现

:::text
entry_points={'console_scripts': [
        'django-admin = django.core.management:execute_from_command_line',
    ]},

通过entry_points,我们可以将python函数注册到系统,这对于用python写系统应用十分有用

#request 首先来看看HttpRequest

        self.GET = QueryDict(mutable=True)
        self.POST = QueryDict(mutable=True)

###QueryDict request的两个GET和POST属性是QueryDict. QueryDict集成自MultiValueDict

MultiValueDict来自django/django/utils/datastructures.py,是django为自身打造的一种抽象数据结构,这个抽象数据结构主要是为了解决这个问题

This class exists to solve the irritating problem raised by cgi.parse_qs,which returns a list for every key, even though most Web forms submitsingle name-value pairs.

###MultiPartParser MultiPartParser类的主要作用是:

Multi-part parsing for file uploads.


更多的可用属性和方法参考:Request and response objects

#response HttpResponse

An HTTP response class with a string as content. This content that can be read, appended to or replaced.

###JsonResponse django/django/http/response.py JsonResponse

:::text
class JsonResponse(HttpResponse):
		...
        kwargs.setdefault('content_type', 'application/json')
        data = json.dumps(data, cls=encoder)
        super(JsonResponse, self).__init__(content=data, **kwargs)

#middleware

Middleware is a framework of hooks into Django’s request/response processing. It’s a light, low-level “plugin” system for globally altering Django’s input or output.

我们关注一下几个middleware

    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',

###SessionMiddleware

#####process_request

	
    def __init__(self):
        engine = import_module(settings.SESSION_ENGINE)
        self.SessionStore = engine.SessionStore
    def process_request(self, request):
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
        request.session = self.SessionStore(session_key)

#####process_response

process_response() is called on all responses before they’re returned to the browser.

                        response.set_cookie(settings.SESSION_COOKIE_NAME,
                                request.session.session_key, max_age=max_age,
                                expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
                                path=settings.SESSION_COOKIE_PATH,
                                secure=settings.SESSION_COOKIE_SECURE or None,
                                httponly=settings.SESSION_COOKIE_HTTPONLY or None)

###CommonMiddleware 使用条件分支来过滤非法客户端

        if 'HTTP_USER_AGENT' in request.META:
            for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
                if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
                    logger.warning('Forbidden (User agent): %s', request.path,
                        extra={
                            'status_code': 403,
                            'request': request
                        }
                    )
                    return http.HttpResponseForbidden('<h1>Forbidden</h1>')

ETag header的处理也在CommonMiddleware

###CsrfViewMiddleware #####process_view

        if getattr(callback, 'csrf_exempt', False):
            return None

callback come from def process_view(self, request, callback, callback_args, callback_kwargs):,callback是装饰器?

###AuthenticationMiddleware #####process_request

    def process_request(self, request):
        assert hasattr(request, 'session'), (
            "The Django authentication middleware requires session middleware "
            "to be installed. Edit your MIDDLEWARE_CLASSES setting to insert "
            "'django.contrib.sessions.middleware.SessionMiddleware' before "
            "'django.contrib.auth.middleware.AuthenticationMiddleware'."
        )
        request.user = SimpleLazyObject(lambda: get_user(request))

注意断言(assert)的使用,这里设置了request.user,并且

The Django authentication middleware requires session middleware

###get_user get_user

#backends ###ModelBackend By default, AUTHENTICATION_BACKENDS is set to: ['django.contrib.auth.backends.ModelBackend']

###CASBackend look at CASBackend

#storage system

###qiniu


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK