首页 > 其他分享 >【23.0】Django框架之中间件引入

【23.0】Django框架之中间件引入

时间:2024-04-07 18:35:17浏览次数:23  
标签:process 中间件 self request Django token 23.0 response

【一】Django中间件介绍

【1】什么是Django中间件

  • Django中间件是一个轻量级、可重用的组件,用于处理Django请求和响应的过程。

  • 它提供了对请求和响应进行全局处理的机制,可以在请求达到视图之前进行预处理或在响应返回给客户端之前进行后处理。

  • 中间件是按照顺序依次执行的,每个中间件都可以对请求和响应进行修改、补充或处理。

  • 在Django的settings.py配置文件中,通过MIDDLEWARE设置来定义中间件的顺序。

【2】作用:

  • 认证和授权:

    • 中间件可以在请求到达视图之前进行用户认证和权限验证,确保只有经过授权的用户才能访问敏感资源。
  • 请求和响应处理:

    • 中间件可以在请求到达视图之前对请求进行预处理

      • 例如添加请求头信息、检查请求参数的合法性等操作。
    • 同时,在视图函数返回响应给客户端之前,中间件还可以对响应进行后处理

      • 例如添加额外的响应头、包装响应数据等操作。
  • 异常处理:

    • 中间件还可以捕获视图函数中可能抛出的异常,并做相应的处理
      • 例如记录异常日志、返回自定义错误信息等。
  • 性能优化:

    • 通过中间件,可以对请求进行性能监测、缓存处理、压缩响应等操作,提升网站的整体性能。

【3】示例

class MyMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # 在视图函数调用之前的预处理逻辑
        # ...

        response = self.get_response(request)

        # 在响应返回给客户端之前的后处理逻辑
        # ...

        return response

【二】Django请求生命周期流程图

1

  • 当客户端发送一个请求到Django应用程序时,Django会按照一定的生命周期流程处理该请求。
    • 下面是Django请求的典型生命周期流程图:
  • 客户端发出HTTP请求。
  • 请求被Web服务器接收并传递给Django应用程序。
  • Django中的WSGI中间件开始处理请求,并可进行一些预处理操作。
  • 中间件将请求传递给URL分发器(URL Dispatcher)。
  • URL分发器根据URL模式将请求路由到相应的视图函数或处理器(View/Handler)。
  • 视图函数或处理器执行相应的业务逻辑,可能会与数据库等外部资源交互。
  • 视图函数或处理器返回一个HTTP响应对象。
  • 响应对象经过中间件,可以在此进行后处理操作。
  • 响应被发送给Web服务器。
  • Web服务器将响应发送回客户端。

【三】Django中间件是Django的门户

  • 请求发来的时候需要先经过中间件才能到达真正的Django后端
  • 响应返回的时候,最后也需要进过中间件返回发送出去

【四】Django中间件源码分析

【1】默认的五个中间件详解

(1)SecurityMiddleware

  • django.middleware.security.SecurityMiddleware
    • 安全中间件负责处理与网站安全相关的任务
    • 例如设置HTTP头部,防止跨站脚本攻击(XSS),点击劫持等。
    • 它可以通过配置自定义安全策略来确保网站的安全性。

(2)SessionMiddleware

  • django.contrib.sessions.middleware.SessionMiddleware
    • 会话中间件负责处理用户会话的创建之间存储和检索用户数据。
    • 它基于浏览器提供的Cookie或URL传递的会话ID进行会话跟踪,并将会话数据存储在后端数据库或缓存中,以实现用户状态的跨请求保持。

(3)CommonMiddleware

  • django.middleware.common.CommonMiddleware
    • 通用中间件提供了一些常见而关键的HTTP请求处理功能
    • 例如,根据请求的HTTP头信息设置语言、时区等。
    • 此外,它还处理静态文件的serving,包括收集静态文件,为其生成URL,并在开发模式下提供静态文件的serving。

(4)CsrfViewMiddleware

  • django.middleware.csrf.CsrfViewMiddleware
    • CSRF(Cross-Site Request Forgery)中间件用于防止跨站请求伪造攻击。
    • 它在每个POST请求中验证一个CSRF标记,确保请求是通过合法的表单提交得到的,从而保护用户免受恶意站点的攻击。

(5)AuthenticationMiddleware

  • django.contrib.auth.middleware.AuthenticationMiddleware
    • 认证中间件负责处理用户身份认证相关的任务
    • 例如将认证信息关联到请求对象上,为每个请求提供一个user对象,以便在请求处理过程中轻松地获取和使用用户身份信息。

(6)MessageMiddleware

  • django.contrib.messages.middleware.MessageMiddleware
    • 消息中间件用于在请求处理过程中存储和传递临时的、一次性的用户消息。
    • 它允许在HTTP重定向之间跨请求传递消息,例如成功或错误提示,以改善用户体验。

(7)XFrameOptionsMiddleware

  • django.middleware.clickjacking.XFrameOptionsMiddleware
    • 点击劫持中间件用于防止页面被嵌入到其他网站中,从而提供一定的点击劫持保护。
    • 它通过设置X-Frame-Options HTTP头部来限制页面的显示方式,从而防止恶意网页通过iframe等方式嵌入当前网页。

【2】源码剖析

(1)源码

  • SessionMiddleware源码
class SessionMiddleware(MiddlewareMixin):
    # RemovedInDjango40Warning: when the deprecation ends, replace with:
    #   def __init__(self, get_response):
    def __init__(self, get_response=None):
        super().__init__(get_response)
        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)

    def process_response(self, request, response):
        """
        If request.session was modified, or if the configuration is to save the
        session every time, save the changes and set a session cookie or delete
        the session cookie if the session has been emptied.
        """
        try:
            accessed = request.session.accessed
            modified = request.session.modified
            empty = request.session.is_empty()
        except AttributeError:
            return response
        # First check if we need to delete this cookie.
        # The session should be deleted only if the session is entirely empty.
        if settings.SESSION_COOKIE_NAME in request.COOKIES and empty:
            response.delete_cookie(
                settings.SESSION_COOKIE_NAME,
                path=settings.SESSION_COOKIE_PATH,
                domain=settings.SESSION_COOKIE_DOMAIN,
                samesite=settings.SESSION_COOKIE_SAMESITE,
            )
            patch_vary_headers(response, ('Cookie',))
        else:
            if accessed:
                patch_vary_headers(response, ('Cookie',))
            if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty:
                if request.session.get_expire_at_browser_close():
                    max_age = None
                    expires = None
                else:
                    max_age = request.session.get_expiry_age()
                    expires_time = time.time() + max_age
                    expires = http_date(expires_time)
                # Save the session data and refresh the client cookie.
                # Skip session save for 500 responses, refs #3881.
                if response.status_code != 500:
                    try:
                        request.session.save()
                    except UpdateError:
                        raise SessionInterrupted(
                            "The request's session was deleted before the "
                            "request completed. The user may have logged "
                            "out in a concurrent request, for example."
                        )
                    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,
                        samesite=settings.SESSION_COOKIE_SAMESITE,
                    )
        return response
  • CsrfViewMiddleware源码
class CsrfViewMiddleware(MiddlewareMixin):
    """
    Require a present and correct csrfmiddlewaretoken for POST requests that
    have a CSRF cookie, and set an outgoing CSRF cookie.

    This middleware should be used in conjunction with the {% csrf_token %}
    template tag.
    """
    # The _accept and _reject methods currently only exist for the sake of the
    # requires_csrf_token decorator.
    def _accept(self, request):
        # Avoid checking the request twice by adding a custom attribute to
        # request.  This will be relevant when both decorator and middleware
        # are used.
        request.csrf_processing_done = True
        return None

    def _reject(self, request, reason):
        response = _get_failure_view()(request, reason=reason)
        log_response(
            'Forbidden (%s): %s', reason, request.path,
            response=response,
            request=request,
            logger=logger,
        )
        return response

    def _get_token(self, request):
        if settings.CSRF_USE_SESSIONS:
            try:
                return request.session.get(CSRF_SESSION_KEY)
            except AttributeError:
                raise ImproperlyConfigured(
                    'CSRF_USE_SESSIONS is enabled, but request.session is not '
                    'set. SessionMiddleware must appear before CsrfViewMiddleware '
                    'in MIDDLEWARE.'
                )
        else:
            try:
                cookie_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
            except KeyError:
                return None

            csrf_token = _sanitize_token(cookie_token)
            if csrf_token != cookie_token:
                # Cookie token needed to be replaced;
                # the cookie needs to be reset.
                request.csrf_cookie_needs_reset = True
            return csrf_token

    def _set_token(self, request, response):
        if settings.CSRF_USE_SESSIONS:
            if request.session.get(CSRF_SESSION_KEY) != request.META['CSRF_COOKIE']:
                request.session[CSRF_SESSION_KEY] = request.META['CSRF_COOKIE']
        else:
            response.set_cookie(
                settings.CSRF_COOKIE_NAME,
                request.META['CSRF_COOKIE'],
                max_age=settings.CSRF_COOKIE_AGE,
                domain=settings.CSRF_COOKIE_DOMAIN,
                path=settings.CSRF_COOKIE_PATH,
                secure=settings.CSRF_COOKIE_SECURE,
                httponly=settings.CSRF_COOKIE_HTTPONLY,
                samesite=settings.CSRF_COOKIE_SAMESITE,
            )
            # Set the Vary header since content varies with the CSRF cookie.
            patch_vary_headers(response, ('Cookie',))

    def process_request(self, request):
        csrf_token = self._get_token(request)
        if csrf_token is not None:
            # Use same token next time.
            request.META['CSRF_COOKIE'] = csrf_token

    def process_view(self, request, callback, callback_args, callback_kwargs):
        if getattr(request, 'csrf_processing_done', False):
            return None

        # Wait until request.META["CSRF_COOKIE"] has been manipulated before
        # bailing out, so that get_token still works
        if getattr(callback, 'csrf_exempt', False):
            return None

        # Assume that anything not defined as 'safe' by RFC7231 needs protection
        if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
            if getattr(request, '_dont_enforce_csrf_checks', False):
                # Mechanism to turn off CSRF checks for test suite.
                # It comes after the creation of CSRF cookies, so that
                # everything else continues to work exactly the same
                # (e.g. cookies are sent, etc.), but before any
                # branches that call reject().
                return self._accept(request)

            if request.is_secure():
                # Suppose user visits http://example.com/
                # An active network attacker (man-in-the-middle, MITM) sends a
                # POST form that targets https://example.com/detonate-bomb/ and
                # submits it via JavaScript.
                #
                # The attacker will need to provide a CSRF cookie and token, but
                # that's no problem for a MITM and the session-independent
                # secret we're using. So the MITM can circumvent the CSRF
                # protection. This is true for any HTTP connection, but anyone
                # using HTTPS expects better! For this reason, for
                # https://example.com/ we need additional protection that treats
                # http://example.com/ as completely untrusted. Under HTTPS,
                # Barth et al. found that the Referer header is missing for
                # same-domain requests in only about 0.2% of cases or less, so
                # we can use strict Referer checking.
                referer = request.META.get('HTTP_REFERER')
                if referer is None:
                    return self._reject(request, REASON_NO_REFERER)

                referer = urlparse(referer)

                # Make sure we have a valid URL for Referer.
                if '' in (referer.scheme, referer.netloc):
                    return self._reject(request, REASON_MALFORMED_REFERER)

                # Ensure that our Referer is also secure.
                if referer.scheme != 'https':
                    return self._reject(request, REASON_INSECURE_REFERER)

                # If there isn't a CSRF_COOKIE_DOMAIN, require an exact match
                # match on host:port. If not, obey the cookie rules (or those
                # for the session cookie, if CSRF_USE_SESSIONS).
                good_referer = (
                    settings.SESSION_COOKIE_DOMAIN
                    if settings.CSRF_USE_SESSIONS
                    else settings.CSRF_COOKIE_DOMAIN
                )
                if good_referer is not None:
                    server_port = request.get_port()
                    if server_port not in ('443', '80'):
                        good_referer = '%s:%s' % (good_referer, server_port)
                else:
                    try:
                        # request.get_host() includes the port.
                        good_referer = request.get_host()
                    except DisallowedHost:
                        pass

                # Create a list of all acceptable HTTP referers, including the
                # current host if it's permitted by ALLOWED_HOSTS.
                good_hosts = list(settings.CSRF_TRUSTED_ORIGINS)
                if good_referer is not None:
                    good_hosts.append(good_referer)

                if not any(is_same_domain(referer.netloc, host) for host in good_hosts):
                    reason = REASON_BAD_REFERER % referer.geturl()
                    return self._reject(request, reason)

            # Access csrf_token via self._get_token() as rotate_token() may
            # have been called by an authentication middleware during the
            # process_request() phase.
            csrf_token = self._get_token(request)
            if csrf_token is None:
                # No CSRF cookie. For POST requests, we insist on a CSRF cookie,
                # and in this way we can avoid all CSRF attacks, including login
                # CSRF.
                return self._reject(request, REASON_NO_CSRF_COOKIE)

            # Check non-cookie token for match.
            request_csrf_token = ""
            if request.method == "POST":
                try:
                    request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
                except OSError:
                    # Handle a broken connection before we've completed reading
                    # the POST data. process_view shouldn't raise any
                    # exceptions, so we'll ignore and serve the user a 403
                    # (assuming they're still listening, which they probably
                    # aren't because of the error).
                    pass

            if request_csrf_token == "":
                # Fall back to X-CSRFToken, to make things easier for AJAX,
                # and possible for PUT/DELETE.
                request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '')

            request_csrf_token = _sanitize_token(request_csrf_token)
            if not _compare_masked_tokens(request_csrf_token, csrf_token):
                return self._reject(request, REASON_BAD_TOKEN)

        return self._accept(request)

    def process_response(self, request, response):
        if not getattr(request, 'csrf_cookie_needs_reset', False):
            if getattr(response, 'csrf_cookie_set', False):
                return response

        if not request.META.get("CSRF_COOKIE_USED", False):
            return response

        # Set the CSRF cookie even if it's already set, so we renew
        # the expiry timer.
        self._set_token(request, response)
        response.csrf_cookie_set = True
        return response

(2)精简

  • CsrfViewMiddleware精简
class CsrfViewMiddleware(MiddlewareMixin):

    # requires_csrf_token decorator.
    def _accept(self, request):
     
        request.csrf_processing_done = True
        return None

    def _reject(self, request, reason):
        
        return response

    def _get_token(self, request):
       
            return csrf_token

    def _set_token(self, request, response):
        

    def process_request(self, request):
        csrf_token = self._get_token(request)
        if csrf_token is not None:
            # Use same token next time.
            request.META['CSRF_COOKIE'] = csrf_token

    def process_view(self, request, callback, callback_args, callback_kwargs):
       

        return self._accept(request)

    def process_response(self, request, response):
        if not getattr(request, 'csrf_cookie_needs_reset', False):
            if getattr(response, 'csrf_cookie_set', False):
                return response

        if not request.META.get("CSRF_COOKIE_USED", False):
            return response
        self._set_token(request, response)
        response.csrf_cookie_set = True
        return response

  • SessionMiddleware源码精简
class SessionMiddleware(MiddlewareMixin):

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

    def process_response(self, request, response):
        
        return response

【五】中间件方法

  • Django支持程序员自定义中间件
    • 并且暴漏给程序员五个中间件

【1】必须掌握的中间件方法

(1)process_request:

(1)执行顺序

  • 请求来的时候需要经过每一个中间件的 process_request 方法
  • 结果的顺序是按照配置文件中注册的中间件从上往下的顺序执行的

(2)没有定义process_request

  • 如果没有定义这个方法,就跳过这个中间件

(3)定义了返回值

  • 如果在自定义中间件中定义了返回值(三板斧),那么请求将不再继续执行,而是直接原路返回(校验失败不允许访问)

(4)总结

  • process_request 方法就是用来 做全局相关的所有限制功能
  • 该方法在每个请求到达视图之前被调用,可以对请求进行预处理。
    • 例如,进行身份验证、访问控制或请求日志记录等操作。
  • 它接收一个HttpRequest对象作为参数,并且没有返回值。

示例:

class AuthenticationMiddleware:
    def process_request(self, request):
        # 在这里进行身份验证操作
        if not request.user.is_authenticated:
            # 如果用户未经身份验证,则返回HttpResponse或重定向到登录页面

(2)process_response:

  • 响应被返回的时候需要结束每一个中间件里面的 process_response 方法

    • 该方法有两个额外的参数
      • request
      • response
  • 该方法必须返回 HttpResponse 对象

    • 默认是response
    • 支持自定义
  • 顺序是按照配置文件中注册过的中间件从下往上依次经过

    • 如果没有定义,则跳过,校验下一个
  • 该方法在每个请求结束并且响应返回到客户端之前被调用。
    • 可以在此处对响应进行处理
    • 例如添加额外的头信息、修改响应内容等。
  • 它接收一个HttpRequest对象和HttpResponse对象作为参数,并且必须返回一个HttpResponse对象。

示例:

class CustomResponseMiddleware:
    def process_response(self, request, response):
        # 在这里对响应进行处理
        response['X-Custom-Header'] = 'Custom Value'
        return response

【2】需要了解的中间件方法:

(1)process_view:

  • 路由匹配成功后执行视图函数之前
  • 会自动执行中间件里面的该方法
  • 顺序是按照配置文件中注册的中间件从上而下的顺序执行
  • 该方法在请求到达视图之前被调用,在视图函数执行前执行。
    • 可以在此处进行一些操作
    • 如修改请求参数或进行记录等。
  • 它接收一个HttpRequest对象和一个视图函数作为参数,并且可以返回一个HttpResponse对象或None。

示例:

class LoggingMiddleware:
    def process_view(self, request, view_func, view_args, view_kwargs):
        # 在这里记录日志
        logger.info(f"Request received: {request.path}")
        # 返回None,继续执行原视图函数
        return None

(2)process_template_response:

  • 返回的 HttpResponse 对象有 render 属性的时候才会触发
  • 顺序是按照配置文件中注册了的中间件从下往上依次经过
  • 该方法在视图函数返回一个TemplateResponse对象时调用。
    • 可以在此处修改模板响应
    • 例如添加全局的上下文数据或进行额外的渲染操作。
  • 它接收一个HttpRequest对象和一个TemplateResponse对象作为参数,并且必须返回一个TemplateResponse对象。

示例:

class GlobalContextMiddleware:
    def process_template_response(self, request, response):
        # 在这里添加全局的上下文数据
        response.context_data['global_data'] = "Global Value"
        return response

(3)process_exception:

  • 当视图函数中出现异常的情况下触发
  • 顺序是按照配置文件中注册了的中间件从下往上依次经过
  • 该方法在视图函数抛出异常时被调用。
    • 可以在此处捕获异常并进行处理
    • 例如返回一个定制的错误页面或进行日志记录等。
  • 它接收一个HttpRequest对象和一个异常对象作为参数,可以返回一个HttpResponse对象来替代原始的异常响应。

示例:

class ErrorHandlerMiddleware:
    def process_exception(self, request, exception):
        # 在这里处理异常
        if isinstance(exception, CustomException):
            # 如果自定义异常,返回一个定制的错误页面
            return render(request, 'error.html', {'error': str(exception)})
        else:
            # 默认情况,返回一个500服务器错误
            return HttpResponseServerError("Internal Server Error")

【六】自定义中间件

【1】process_request

【1】路由层

from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/',views.index),
]

【2】视图层

def index(request):
    print("这是视图函数index")
    return HttpResponse("index 的返回值")

【3】配置文件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    # 注册自己的中间件(在应用下创建路径会有提示,但是如果在项目下创建就没有提示,需要自己根据路径书写)
    'app01.mymiddle.my_middle.MyMiddle',
    # 谁先注册就先执行谁
    'app01.mymiddle.my_middle.MyMiddle2',
]

【4】自定义中间件

# -*-coding: Utf-8 -*-
# @File : my_middle .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/7/17

# 引入父类
from django.utils.deprecation import MiddlewareMixin


class MyMiddle(MiddlewareMixin):
    def process_request(self, request):
        print("这是第一个自定义中间件中的 process_request 方法")

class MyMiddle2(MiddlewareMixin):
    def process_request(self, request):
        print("这是第二个自定义中间件中的 process_request 方法")

【5】总结

(1)执行顺序

  • 请求来的时候需要经过每一个中间件的 process_request 方法
  • 结果的顺序是按照配置文件中注册的中间件从上往下的顺序执行的

(2)没有定义process_request

  • 如果没有定义这个方法,就跳过这个中间件

(3)定义了返回值

  • 如果在自定义中间件中定义了返回值(三板斧),那么请求将不再继续执行,而是直接原路返回(校验失败不允许访问)

(4)总结

  • process_request 方法就是用来 做全局相关的所有限制功能

【2】process_response`

# 引入父类
from django.utils.deprecation import MiddlewareMixin


class MyMiddle(MiddlewareMixin):
    def process_request(self, request):
        print("这是第一个自定义中间件中的 process_request 方法")

    def process_response(self, request, response):
        '''
        
        :param request: 
        :param response: 就是Django返回给浏览器的内容
        :return: 
        '''
        print("这是第一个自定义中间件中的 process_response 方法")
        # 必须返回 responser
        return response
  • 响应被返回的时候需要结束每一个中间件里面的 process_response 方法

    • 该方法有两个额外的参数
      • request
      • response
  • 该方法必须返回 HttpResponse 对象

    • 默认是response
    • 支持自定义
  • 顺序是按照配置文件中注册过的中间件从下往上依次经过

    • 如果没有定义,则跳过,校验下一个

【3】小结

  • 如果在第一个 process_request 方法就已经返回了 HttpResponse 对象,那么响应被返回的时候是经过所有的中间件里面的 process_response 方法还是会发生其他?

    • 会直接走同级别的 process_response 方法 ,然后直接返回
  • flask框架的中间件也有一个类似的方法

    • 但是flask返回数据就必须经过所有中间件里面的 process_response 方法

标签:process,中间件,self,request,Django,token,23.0,response
From: https://www.cnblogs.com/dream-ze/p/18119653

相关文章

  • 【26.1】Django框架之settings配置
    【一】引言Django项目的设置文件位于项目同名目录下,名叫settings.py。这个模块,集合了整个项目方方面面的设置属性,是项目启动和提供服务的根本保证。【二】简述settings.py文件本质上是一个Python模块,带有模块级别的变量。下面是一些示例设置:ALLOWED_HOSTS=['www.examp......
  • 【26.0】Django框架之settings源码
    【一】Django配置文件介绍Django框架默认提供给我们一个配置文件在我们项目根目录下的setting.py文件中,在里面我们可以看到很多的配置项并且我们能够自主的添加相应的配置但是其实这个文件只是Django暴露出来给我们的一个接口文件,在Django内部还存在一个更加强大的配置文件......
  • 【25.0】Django框架之auth模块
    【一】Auth模块引入我们在创建一个Django项目之后,直接执行数据库迁移命令会自动生成很多表django_sessionauth_userDjango在启动之后就可以直接访问admin路由,需要输入用户名和密码,数据参考的就是auth_user表,并且必须是管理员用户才能进入【二】创建超级用户(管理员)......
  • python计算机毕设【附源码】汉服文化管理系统(django+mysql+论文)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:汉服,作为中国古代汉族传统服饰的总称,承载了丰富的历史文化遗产和审美价值。近年来,随着国民文化自信心的提升和传统文化复兴的浪潮,汉服文化逐渐走进了公众的......
  • 【26.2】Django框架之settings核心配置项
    【一】前言【1】引言Django的默认配置文件中,包含上百条配置项目其中很多是我们‘一辈子’都不碰到或者不需要单独配置的这些项目在需要的时候再去查手册。【2】强调配置的默认值不是在settings.py文件中!不要以为settings.py中的配置值就是默认值,参考前文。settings.py......
  • Django单程序运行
    1、增加环境变量并且配置#确保运行在最model类之前importosimportdjangoos.environ.setdefault('DJANGO_SETTINGS_MODULE','SmsProject.settings')django.setup()2、如果使用Pycharm还需要做如下配置3、运行程序importosimportdjangoos.environ.setdefault(......
  • 物流系统django版本
    1,创建modelspyfromdjango.dbimportmodelsclassGoods(models.Model):  id=models.AutoField(primary_key=True)  name=models.CharField('货物名称',default='',max_length=50)  source=models.CharField('渠道',max_length=......
  • Java/Mysql数据库+django学生就业管理系统 24237(免费领源码)计算机毕业设计项目推荐上
    学生就业管理系统摘 要随着社会的快速发展和人们生活水平的不断提高,旅游已逐渐成为人们生活的重要组成部分,用户能够获取旅游信息的渠道也随信息技术的广泛应用而增加。大量未经过滤的信息在展示给用户的同时,也淹没了用户真正感兴趣的信息。为了方便用户快速定位自己感兴趣......
  • python计算机毕设【附源码】便利店收银管理系统(django+mysql+论文)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着社会的发展和经济的进步,便利店作为一种新型的零售业态在城市中迅速崛起。便利店以其便捷的地理位置、丰富的商品种类和高效的服务赢得了消费者的青睐。......
  • Django框架之ORM操作
    一、选择数据库1、默认数据库Django默认的数据库是sqlite3数据库DATABASES={'default':{'ENGINE':'django.db.backends.sqlite3','NAME':BASE_DIR/'db.sqlite3',}}2、指定数据库修改连接到MySQL数据库DATABASES......