• python---django的模块简便使用


    一:登录操作

    from django.contrib.auth import authenticate,login,logout  #可以用来做登录验证
    from django.contrib.auth.decorators import login_required  #装饰器,用于对用户是否登录进行验证

    1.简单使用:

    def acc_login(request):
        error_msg = ''
        if request.method == "POST":
            username = request.POST.get("username")
            password = request.POST.get("password")
            user = authenticate(username=username,password=password)    #进行用户验证
            if user:
                login(request,user) #登录状态,添加入session, request.user = user
    
                return redirect(request.GET.get("next","/"))
            else:
                error_msg = "Wrong Username Or Password"
    
        return render(request,"login.html",{"error_msg":error_msg})
    
    def acc_logout(request):
        logout(request) #清除session数据
        return redirect("/login.html")
    
    
    from django.contrib.auth.decorators import login_required
    
    @login_required
    def dashboard(request):
    
        return render(request,"Sale/dashboard.html")

    注意:使用@login_required需要我们配置

    LOGIN_URL = "/login.html"  #默认是在accounts/login路由下跳转

    2.方法了解

    (1)authenticate方法

        def authenticate(self, request, username=None, password=None, **kwargs):
            if username is None:
                username = kwargs.get(UserModel.USERNAME_FIELD)
            try:
                user = UserModel._default_manager.get_by_natural_key(username)  #根据用户名获取用户对象
            except UserModel.DoesNotExist:
                # Run the default password hasher once to reduce the timing
                # difference between an existing and a non-existing user (#20760).
                UserModel().set_password(password)
            else:
                if user.check_password(password) and self.user_can_authenticate(user):  #根据密码进行登录验证,以及获取用户的操作权限
                    return user
    UserModel = get_user_model()
    def get_user_model():  #返回用户表对象,对象由AUTH_USER_MODEL指定,默认是auth.User默认数据表,我们可以在自己的setting文件中进行覆盖
        """
        Returns the User model that is active in this project.
        """
        return django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False)

    (2)login方法

    def login(request, user, backend=None):
    def login(request, user, backend=None):
        """
        Persist a user id and a backend in the request. This way a user doesn't
        have to reauthenticate on every request. Note that data set during
        the anonymous session is retained when the user logs in.
        """
        session_auth_hash = ''
        if user is None:
            user = request.user
        if hasattr(user, 'get_session_auth_hash'):
            session_auth_hash = user.get_session_auth_hash()
    
        if SESSION_KEY in request.session:
            if _get_user_session_key(request) != user.pk or (
                    session_auth_hash and
                    not constant_time_compare(request.session.get(HASH_SESSION_KEY, ''), session_auth_hash)):
                # To avoid reusing another user's session, create a new, empty
                # session if the existing session corresponds to a different
                # authenticated user.
                request.session.flush()
        else:
            request.session.cycle_key()
    
        try:
            backend = backend or user.backend
        except AttributeError:
            backends = _get_backends(return_tuples=True)
            if len(backends) == 1:
                _, backend = backends[0]
            else:
                raise ValueError(
                    'You have multiple authentication backends configured and '
                    'therefore must provide the `backend` argument or set the '
                    '`backend` attribute on the user.'
                )
    
        request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
        request.session[BACKEND_SESSION_KEY] = backend
        request.session[HASH_SESSION_KEY] = session_auth_hash
        if hasattr(request, 'user'):
            request.user = user
        rotate_token(request)
        user_logged_in.send(sender=user.__class__, request=request, user=user)
    设置session,向request中添加user属性,可以直接使用request.user获取User表对象

    (3)logout方法

    def logout(request):
    def logout(request):
        """
        Removes the authenticated user's ID from the request and flushes their
        session data.
        """
        # Dispatch the signal before the user is logged out so the receivers have a
        # chance to find out *who* logged out.
        user = getattr(request, 'user', None)
        if hasattr(user, 'is_authenticated') and not user.is_authenticated:
            user = None
        user_logged_out.send(sender=user.__class__, request=request, user=user)
    
        # remember language choice saved to session
        language = request.session.get(LANGUAGE_SESSION_KEY)
    
        request.session.flush()
    
        if language is not None:
            request.session[LANGUAGE_SESSION_KEY] = language
    
        if hasattr(request, 'user'):
            from django.contrib.auth.models import AnonymousUser
            request.user = AnonymousUser()
    清空session,删除request.user

    (4)login_required方法

    def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None):#function是我们装饰的函数名,redirect_field_name是跳转时所带的参数,默认next
        """
        Decorator for views that checks that the user is logged in, redirecting
        to the log-in page if necessary.
        """
        actual_decorator = user_passes_test(
            lambda u: u.is_authenticated,
            login_url=login_url,
            redirect_field_name=redirect_field_name
        )
        if function:
            return actual_decorator(function)
        return actual_decorator
    函数体
    def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
        """
        Decorator for views that checks that the user passes the given test,
        redirecting to the log-in page if necessary. The test should be a callable
        that takes the user object and returns True if the user passes.
        """
    
        def decorator(view_func):
            @wraps(view_func, assigned=available_attrs(view_func))
            def _wrapped_view(request, *args, **kwargs):
                if test_func(request.user):
                    return view_func(request, *args, **kwargs)
                path = request.build_absolute_uri()
                resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
                # If the login url is the same scheme and net location then just
                # use the path as the "next" url.
                login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
                current_scheme, current_netloc = urlparse(path)[:2]
                if ((not login_scheme or login_scheme == current_scheme) and
                        (not login_netloc or login_netloc == current_netloc)):
                    path = request.get_full_path()
                from django.contrib.auth.views import redirect_to_login
                return redirect_to_login(
                    path, resolved_login_url, redirect_field_name)
            return _wrapped_view
        return decorator
    装饰器方法

     二:csrf的多种使用方法

    from django.views.decorators.csrf import csrf_exempt

    1.需求分析

    当我们需要对某一个view方法去掉csrf_token验证时。总不至于去注释掉所有的csrf验证吧
    # 'django.middleware.csrf.CsrfViewMiddleware',

    那么我们需要去取消某一个方法的csrf验证

    2.实现代码

    1.FBV:直接使用装饰器方法

    @csrf_exempt
    def asset(request):
        pass

    2.CBV:需要再去引入一个模块(其实也可以直接使用)

    from django.utils.decorators import method_decorator
    class AssetView(View):
        @method_decorator(csrf_exempt)
        def dispatch(self, request, *args, **kwargs):
            return super(AssetView, self).dispatch(request, *args, **kwargs)
        def post(self,request,*args,**kwargs):
         pass

       def put(self,request,*args,**kwargs):
         pass
    其中dispatch()方法:作用是将任务分发到正确的方法上。因为需要过滤掉csrf的方法不止post,还有put等,所以在dispatch中过滤掉csrf,那么在其他的方法上可以不用去管

    3.在url中进行过滤

    from django.conf.urls import url
    from API import views as v1
    from django.views.decorators.csrf import csrf_exempt
    
    
    urlpatterns = [
        url(r'^asset',csrf_exempt(v1.AssetView.as_view())),  
    ]

     三:import导入的多种方法(用于反射)

    1.一般导入模块直接使用import

    import 模块  #一般我们是直接使用import导入对应模块
    from 包 import 模块  #多层导入 

    2.需求:现有字符串代表各个模块,如何通过反射获取该模块

    (1)使用__import__

    __import__("模块")  

    __import__("层一.层二.层三.模块",fromlist=True) #对于多层,我们使用.连接。注意:fromlist需要添加为True,不然只会导入层一,调用的使用我们还要一级一级向下找,不方便

    def __import__(name, globals=None, locals=None, fromlist=(), level=0): # real signature unknown; restored from __doc__
    When importing a module from a package, note that __import__('A.B', ...)
    returns package A when fromlist is empty, but its submodule B when
    fromlist is not empty.
    package:test3    --->   包下面有t2.py文件,定义test2方法
    无fromlist:
    md = __import__("test3.t2")
    md.t2.test2()  #test2
    
    
    有fromlist
    md = __import__("test3.t2",fromlist=True)
    md.test2()
    演示结果

    (2)使用importlib.import_module

    def import_module(name, package=None):
    #如果是相对导入的话,第二个参数是需要的
    
        The 'package' argument is required when performing a relative import. It
        specifies the package to use as the anchor point from which to resolve the
        relative import to an absolute import.
    md = importlib.import_module("test3.t2")
    md.test2()  #test2
    md = importlib.import_module(".t2","test3")  #.t2代表时相对于test3下的相对路径,就是相当于将前后连接test3.t2
    md.test2()
    md = importlib.import_module("test3.t1.t11")
    md.test11()
    
    md = importlib.import_module(".t1.t11","test3")
    md.test11()
    
    #test11
    #test11
    再多一级
  • 相关阅读:
    理解C#中的 async await
    kube-proxy IPVS 模式的工作原理
    Kilo 使用教程
    Wireguard 全互联模式(full mesh)配置指南
    我为什么不鼓吹 WireGuard
    iTerm2 实现 ssh 自动登录,并使用 Zmodem 实现快速传输文件
    在 Docker Desktop 中启用 K8s 服务
    ABP 适用性改造
    ABP 适用性改造
    在 ASP.NET Core 应用中使用 Cookie 进行身份认证
  • 原文地址:https://www.cnblogs.com/ssyfj/p/9087545.html
Copyright © 2020-2023  润新知