Django 和 DRF 的各种 login 汇总

文章中和 RDS 项目中得到灵感:DjangoRestFramework 也是有自己的登录页面的

  1. DjangoRestFramework 的登录页
    在这里插入图片描述
    urls.py

    from rest_framework import routers
    from rest_framework.authtoken import views as drf_auth_views
    
    urlpatterns = [
         .........  
         # 学习 restframework 的 login 和 TokenAuthentication
         # https://blog.csdn.net/qq_39980136/article/details/89503850
         url(r'^drf/', include('rest_framework.urls')),               ----- DRF 的登录 url 和 视图函数
         url(r'^drf_token/', drf_auth_views.obtain_auth_token),       ----- DRF 居然给提供了这么现成的接口
         url(r'^auth/', include('django.contrib.auth.urls')), 
    ]
    

D:\xxx\venv\Lib\site-packages\rest_framework\urls.py

from django.conf.urls import url
from django.contrib.auth import views

app_name = 'rest_framework'
urlpatterns = [
    url(r'^login/$', views.LoginView.as_view(template_name='rest_framework/login.html'), name='login'),
    url(r'^logout/$', views.LogoutView.as_view(), name='logout'),
]

发现了上图就是 D:\xxx\venv\Lib\site-packages\rest_framework\templates\rest_framework\login.html

  1. Django 原生的登录页, ‘registration/login.html’ Django 框架中并没有该文件只是文件名字固定了,需要开发者提供内容

仔细分析上面的代码 D:\xxx\venv\Lib\site-packages\rest_framework\urls.py 可以看到其使用的就是 Django 原生的 LoginView
在这里插入图片描述

urls.py

from rest_framework import routers
from rest_framework.authtoken import views as drf_auth_views

urlpatterns = [
    .........  
    url(r'^auth/', include('django.contrib.auth.urls')), 
]

D:\xxx\venv\Lib\site-packages\django\contrib\auth\urls.py

from django.conf.urls import url
from django.contrib.auth import views

urlpatterns = [
    url(r'^login/$', views.LoginView.as_view(), name='login'),
    url(r'^logout/$', views.LogoutView.as_view(), name='logout'),

    url(r'^password_change/$', views.PasswordChangeView.as_view(), name='password_change'),
    url(r'^password_change/done/$', views.PasswordChangeDoneView.as_view(), name='password_change_done'),
    url(r'^password_reset/$', views.PasswordResetView.as_view(), name='password_reset'),
    url(r'^password_reset/done/$', views.PasswordResetDoneView.as_view(), name='password_reset_done'),
    url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
        views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    url(r'^reset/done/$', views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]

D:\xxx\venv\Lib\site-packages\django\contrib\auth\views.py

class LoginView(SuccessURLAllowedHostsMixin, FormView):
    """
    Displays the login form and handles the login action.
    """
    form_class = AuthenticationForm
    authentication_form = None
    redirect_field_name = REDIRECT_FIELD_NAME
    template_name = 'registration/login.html'      -------Django 框架中并没有该文件只是文件名字固定了,需要开发者提供内容
    redirect_authenticated_user = False
    extra_context = None

    @method_decorator(sensitive_post_parameters())
    @method_decorator(csrf_protect)
    @method_decorator(never_cache)
    def dispatch(self, request, *args, **kwargs):
        if self.redirect_authenticated_user and self.request.user.is_authenticated:
            redirect_to = self.get_success_url()
            if redirect_to == self.request.path:
                raise ValueError(
                    "Redirection loop for authenticated user detected. Check that "
                    "your LOGIN_REDIRECT_URL doesn't point to a login page."
                )
            return HttpResponseRedirect(redirect_to)
        return super(LoginView, self).dispatch(request, *args, **kwargs)

    def get_success_url(self):
        url = self.get_redirect_url()
        return url or resolve_url(settings.LOGIN_REDIRECT_URL)


[root@JXQ-240-90-228 site-packages]# find . -name login.html
./Django-1.11.16-py2.7.egg/django/contrib/admin/templates/admin/login.html
./djangorestframework-3.8.2-py2.7.egg/rest_framework/templates/rest_framework/login.html
[root@JXQ-240-90-228 site-packages]# 
  1. Django admin URL 的 login
    在这里插入图片描述

urls.py:

from app01 import views
from app02 import views as app02_view
from app03 import views as app03_view
from rest_framework import routers
app02_router = routers.DefaultRouter()
app02_router.register(r'autoregister', app02_view.RoleViewSet)

from rest_framework.authtoken import views as drf_auth_views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

D:\xxx\venv\Lib\site-packages\django\contrib\admin\sites.py

class AdminSite(object):
    ........
    def get_urls(self):
        from django.conf.urls import url, include
        # Since this module gets imported in the application's root package,
        # it cannot import models from other applications at the module level,
        # and django.contrib.contenttypes.views imports ContentType.
        from django.contrib.contenttypes import views as contenttype_views

        def wrap(view, cacheable=False):
            def wrapper(*args, **kwargs):
                return self.admin_view(view, cacheable)(*args, **kwargs)
            wrapper.admin_site = self
            return update_wrapper(wrapper, view)

        # Admin-site-wide views.
        urlpatterns = [
            url(r'^$', wrap(self.index), name='index'),
            url(r'^login/$', self.login, name='login'),
            url(r'^logout/$', wrap(self.logout), name='logout'),
            url(r'^password_change/$', wrap(self.password_change, cacheable=True), name='password_change'),
            url(r'^password_change/done/$', wrap(self.password_change_done, cacheable=True),
                name='password_change_done'),
            url(r'^jsi18n/$', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),
            url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$', wrap(contenttype_views.shortcut),
                name='view_on_site'),
        ]

        # Add in each model's views, and create a list of valid URLS for the
        # app_index
        valid_app_labels = []
        for model, model_admin in self._registry.items():
            urlpatterns += [
                url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)),
            ]
            if model._meta.app_label not in valid_app_labels:
                valid_app_labels.append(model._meta.app_label)

        # If there were ModelAdmins registered, we should have a list of app
        # labels for which we need to allow access to the app_index view,
        if valid_app_labels:
            regex = r'^(?P<app_label>' + '|'.join(valid_app_labels) + ')/$'
            urlpatterns += [
                url(regex, wrap(self.app_index), name='app_list'),
            ]
        return urlpatterns

    @property
    def urls(self):
        return self.get_urls(), 'admin', self.name
        
    @never_cache
    def login(self, request, extra_context=None):
        """
        Displays the login form for the given HttpRequest.
        """
        if request.method == 'GET' and self.has_permission(request):
            # Already logged-in, redirect to admin index
            index_path = reverse('admin:index', current_app=self.name)
            return HttpResponseRedirect(index_path)

        from django.contrib.auth.views import LoginView
        # Since this module gets imported in the application's root package,
        # it cannot import models from other applications at the module level,
        # and django.contrib.admin.forms eventually imports User.
        from django.contrib.admin.forms import AdminAuthenticationForm
        context = dict(
            self.each_context(request),
            title=_('Log in'),
            app_path=request.get_full_path(),
            username=request.user.get_username(),
        )
        if (REDIRECT_FIELD_NAME not in request.GET and
                REDIRECT_FIELD_NAME not in request.POST):
            context[REDIRECT_FIELD_NAME] = reverse('admin:index', current_app=self.name)
        context.update(extra_context or {})

        defaults = {
            'extra_context': context,
            'authentication_form': self.login_form or AdminAuthenticationForm,
            'template_name': self.login_template or 'admin/login.html',   --- 就是上图看到的 admin login 页面
        }
        request.current_app = self.name
        return LoginView.as_view(**defaults)(request)
        
site = AdminSite()    ----------正好和 urls.py 中的   url(r'^admin/', admin.site.urls),  呼应
发布了44 篇原创文章 · 获赞 0 · 访问量 3943

猜你喜欢

转载自blog.csdn.net/cpxsxn/article/details/102616760