西游之路——python全栈——Django模块简便使用

目录

一:登录操作
  1.简单使用:
  注意:使用@login_required需要我们配置
  2.方法了解
 二:csrf的多种使用方法
  1.需求分析
  2.实现代码
 三:import导入的多种方法(用于反射)
  1.一般导入模块直接使用import
  2.需求:现有字符串代表各个模块,如何通过反射获取该模块

一:登录操作

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):
 1 def login(request, user, backend=None):
 2     """
 3     Persist a user id and a backend in the request. This way a user doesn't
 4     have to reauthenticate on every request. Note that data set during
 5     the anonymous session is retained when the user logs in.
 6     """
 7     session_auth_hash = ''
 8     if user is None:
 9         user = request.user
10     if hasattr(user, 'get_session_auth_hash'):
11         session_auth_hash = user.get_session_auth_hash()
12 
13     if SESSION_KEY in request.session:
14         if _get_user_session_key(request) != user.pk or (
15                 session_auth_hash and
16                 not constant_time_compare(request.session.get(HASH_SESSION_KEY, ''), session_auth_hash)):
17             # To avoid reusing another user's session, create a new, empty
18             # session if the existing session corresponds to a different
19             # authenticated user.
20             request.session.flush()
21     else:
22         request.session.cycle_key()
23 
24     try:
25         backend = backend or user.backend
26     except AttributeError:
27         backends = _get_backends(return_tuples=True)
28         if len(backends) == 1:
29             _, backend = backends[0]
30         else:
31             raise ValueError(
32                 'You have multiple authentication backends configured and '
33                 'therefore must provide the `backend` argument or set the '
34                 '`backend` attribute on the user.'
35             )
36 
37     request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
38     request.session[BACKEND_SESSION_KEY] = backend
39     request.session[HASH_SESSION_KEY] = session_auth_hash
40     if hasattr(request, 'user'):
41         request.user = user
42     rotate_token(request)
43     user_logged_in.send(sender=user.__class__, request=request, user=user)
44 
45 设置session,向request中添加user属性,可以直接使用request.user获取User表对象
设置session,向request中添加user属性,可以直接使用request.user获取User表对象

 

(3)logout方法

def logout(request): 
 1 def logout(request):
 2     """
 3     Removes the authenticated user's ID from the request and flushes their
 4     session data.
 5     """
 6     # Dispatch the signal before the user is logged out so the receivers have a
 7     # chance to find out *who* logged out.
 8     user = getattr(request, 'user', None)
 9     if hasattr(user, 'is_authenticated') and not user.is_authenticated:
10         user = None
11     user_logged_out.send(sender=user.__class__, request=request, user=user)
12 
13     # remember language choice saved to session
14     language = request.session.get(LANGUAGE_SESSION_KEY)
15 
16     request.session.flush()
17 
18     if language is not None:
19         request.session[LANGUAGE_SESSION_KEY] = language
20 
21     if hasattr(request, 'user'):
22         from django.contrib.auth.models import AnonymousUser
23         request.user = AnonymousUser()
24 
25 清空session,删除request.user
清空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
 1 """
 2     Decorator for views that checks that the user is logged in, redirecting
 3     to the log-in page if necessary.
 4     """
 5     actual_decorator = user_passes_test(
 6         lambda u: u.is_authenticated,
 7         login_url=login_url,
 8         redirect_field_name=redirect_field_name
 9     )
10     if function:
11         return actual_decorator(function)
12     return actual_decorator
函数体

============

 1 def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
 2     """
 3     Decorator for views that checks that the user passes the given test,
 4     redirecting to the log-in page if necessary. The test should be a callable
 5     that takes the user object and returns True if the user passes.
 6     """
 7 
 8     def decorator(view_func):
 9         @wraps(view_func, assigned=available_attrs(view_func))
10         def _wrapped_view(request, *args, **kwargs):
11             if test_func(request.user):
12                 return view_func(request, *args, **kwargs)
13             path = request.build_absolute_uri()
14             resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
15             # If the login url is the same scheme and net location then just
16             # use the path as the "next" url.
17             login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
18             current_scheme, current_netloc = urlparse(path)[:2]
19             if ((not login_scheme or login_scheme == current_scheme) and
20                     (not login_netloc or login_netloc == current_netloc)):
21                 path = request.get_full_path()
22             from django.contrib.auth.views import redirect_to_login
23             return redirect_to_login(
24                 path, resolved_login_url, redirect_field_name)
25         return _wrapped_view
26     return decorator
27 
28 装饰器方法
装饰器方法

二: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.
复制代码
 1 package:test3    --->   包下面有t2.py文件,定义test2方法
 2 无fromlist:
 3 md = __import__("test3.t2")
 4 md.t2.test2()  #test2
 5 
 6 
 7 有fromlist
 8 md = __import__("test3.t2",fromlist=True)
 9 md.test2()
10 
11 演示结果
演示结果

 

(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()
 
 1 md = importlib.import_module("test3.t1.t11")
 2 md.test11()
 3 
 4 md = importlib.import_module(".t1.t11","test3")
 5 md.test11()
 6 
 7 #test11
 8 #test11
 9 
10 再多一级
再多一级

 

posted @ 2018-11-14 19:45  陆游憩  阅读(174)  评论(0编辑  收藏  举报