Django Authentication 用户认证系统


一、 Django的认证系统

Django自带一个用户认证系统,用于处理用户账户、群组、许可和基于cookie的用户会话。

1.1 概览

Django的认证系统包含了身份验证和权限管理两部分。简单地说,身份验证用于核实某个用户是否是合法用户,权限管理则是决定一个合法用户具有哪些权限。这里,“身份验证”这个词同时代指上面两部分的含义。

系统主要包括:

  • 用户
  • 许可
  • 可配置的密码哈希系统
  • 用于用户登录或者限制访问的表单和视图工具
  • 可插拔的后端

类似下面的问题,请使用第三方包:

  • 密码强度检查
  • 登录请求限制
  • 第三方认证

1.2 安装

默认情况下,使用django-admin startproject命令后,认证相关的模块已经自动添加到settings文件内了,如果没有的话,请手动添加。

在 INSTALLED_APPS配置项中:

  1. 'django.contrib.auth': 包含认证框架的核心以及默认模型
  2. 'django.contrib.contenttypes':内容类型系统,用于给模型关联许可

在MIDDLEWARE配置项中:

  1. SessionMiddleware:通过请求管理会话
  2. AuthenticationMiddleware:将会话和用户关联

当配置正确后,运行manage.py migrate命令,创建用户认证系统相关的数据库表以及分配预定义的权限。

二、 使用Django的认证系统

2.1 用户对象

默认的用户包含下面的属性:

  • username
  • password
  • email
  • first_name
  • last_name

2.1.1 创建用户

最直接的办法是使用 create_user()功能:

>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
# 这时,user是一个User类的实例,已经保存在了数据库内,你可以随时修改它的属性,例如:
>>> user.last_name = 'Lennon'
>>> user.save()

如果你已经启用了Django的admin站点,你也可以在web页面上创建用户。

2.1.2 创建超级用户

使用createsuperuser命令

$ python manage.py createsuperuser --username=joe --email=joe@example.com

根据提示输入名字、密码和邮箱地址。

2.1.3 修改密码

Django默认会对密码进行加密,因此,不要企图对密码进行直接操作。这也是为什么要使用一个帮助函数来创建用户的原因。

要修改密码,有两个办法:

  1. 使用命令行: manage.py changepassword username。如果不提供用户名,则会尝试修改当前系统用户的密码。
  2. 使用set_password()方法:
from django.contrib.auth.models import User
u = User.objects.get(username='john')
u.set_password('new password')
u.save()

同样可以在admin中修改密码。

Django提供了views和forms,方便用户自己修改密码。

修改密码后,用户的所有当前会话将被注销。

2.1.4 用户验证

authenticate(**credentials)[source]:

通常接收username与password作为参数进行认证。在认证后端中,有一项通过则返回一个User类对象,一项都没通过或者抛出了PermissionDenied异常,则返回一个None。例如:

from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
# A backend authenticated the credentials
else:
# No backend authenticated the credentials

2.2 权限与授权

Django提供了一个权限系统用于它的admin站点,当然你也可以在你的代码中使用。

使用方法:

  • 必须有“add”授权的用户才可以访问add页面
  • 必须有“change”授权的用户才可以访问change list页面
  • 必须有“delete”授权的用户才可以删除对象

ModelAdmin类提供了 has_add_permission(),has_change_permission()和has_delete_permission()三个方法。User表的对象有两个多对多的字段,groups和user_permissions,可以像普通的model一样访问他们。

myuser.groups.set([group_list])
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()

2.2.1 默认权限

默认情况下,使用manage.py migrate命令时,Django会给每个已经存在的model添加默认的权限。

假设你现在有个app叫做foo,有个model叫做bar,使用下面的方式可以测试默认权限:

add: user.has_perm('foo.add_bar')
change: user.has_perm('foo.change_bar')
delete: user.has_perm('foo.delete_bar')

2.2.2 组

Django提供了一个django.contrib.auth.models.Group模型,该model可用于给用户分组,实现批量管理。用户和组属于多对多的关系。用户自动具有所属组的所有权限。

2.2.3 在代码中创建权限

例如,你可以为myapp中的BlogPost模型添加一个can_publish权限。

from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(
codename='can_publish',
name='Can Publish Posts',
content_type=content_type,
)

然后,你可以通过User模型的user_permissions属性或者Group模型的permissions属性为用户添加该权限。

2.2.4 权限缓存

权限检查后,会被缓存在用户对象中。参考下面的例子:

from django.contrib.auth.models import Permission, User
from django.shortcuts import get_object_or_404 def user_gains_perms(request, user_id):
user = get_object_or_404(User, pk=user_id)
# any permission check will cache the current set of permissions
user.has_perm('myapp.change_bar') permission = Permission.objects.get(codename='change_bar')
user.user_permissions.add(permission) # Checking the cached permission set
user.has_perm('myapp.change_bar') # False # Request new instance of User
# Be aware that user.refresh_from_db() won't clear the cache.
user = get_object_or_404(User, pk=user_id) # Permission cache is repopulated from the database
user.has_perm('myapp.change_bar') # True ...

2.3 在Web请求中的认证

Django使用session和中间件在请求对象中钩住认证系统。

每一次请求中都包含一个request.user属性。如果该用户未登陆,该属性的值是AnonymousUser,如果已经登录,该属性就是一个User模型的实例。

可以使用is_authenticated方法进行判断,如下:

if request.user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...

2.3.1 如何登录用户

login(request, user, backend=None)[source]:

在视图中,使用login()方法登录用户。它接收一个HttpRequest参数和一个User对象参数。该方法会把用户的ID保存在Django的session中。下面是一个认证和登陆的例子:

from django.contrib.auth import authenticate, login

def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
# 跳转到成功页面
...
else:
# 返回一个非法登录的错误页面
...

2.3.2 如何注销用户

logout(request)[source]:

from django.contrib.auth import logout

def logout_view(request):
logout(request)
# Redirect to a success page.

注意,被logout的用户如何没登录,不会抛出错误。

一旦logout,当前请求中的session数据都会被清空。

2.3.3 登陆用户访问限制

原始的办法

在request.user.is_authenticated中重定向到登录页面,如下所示:

from django.conf import settings
from django.shortcuts import redirect def my_view(request):
if not request.user.is_authenticated:
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
# ...

或者显示一个错误信息:

from django.shortcuts import render

def my_view(request):
if not request.user.is_authenticated:
return render(request, 'myapp/login_error.html')
# ...

使用装饰器

login_required(redirect_field_name='next', login_url=None)[source]

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
...

该装饰器工作机制:

  • 如果用户未登陆,重定向到settings.LOGIN_URL,传递当前绝对路径作为url字符串的参数,例如:/accounts/login/?next=/polls/3/
  • 如果用户已经登录,执行正常的视图

此时,默认的url中使用的参数是“next”,如果你想使用自定义的参数,请修改login_required()的redirect_field_name参数,如下所示:

from django.contrib.auth.decorators import login_required

@login_required(redirect_field_name='my_redirect_field')
def my_view(request):
...

如果你这么做了,你还需要重新定制登录模板,因为它引用了redirect_field_name变量。

login_required()方法还有一个可选的longin_url参数。例如:

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
def my_view(request):
...

注意:如果不指定login_url参数,请确保你的settings.LOGIN_URL和登陆视图保持正确的关联。例如:

from django.contrib.auth import views as auth_views
url(r'^accounts/login/$', auth_views.login),

使用LoginRequired mixin

通过继承LoginRequiredMixin类的方式。

在多继承时,该类必须是最左边的父类。

class LoginRequiredMixin(New in Django 1.9.)

根据raise_exception参数的不同,对于未登陆的用户请求,响应不同的结果。

from django.contrib.auth.mixins import LoginRequiredMixin

class MyView(LoginRequiredMixin, View):
login_url = '/login/'
redirect_field_name = 'redirect_to'

进行测试,根据结果决定动作

你也可以直接在视图中进行过滤:

from django.shortcuts import redirect

def my_view(request):
if not request.user.email.endswith('@example.com'):
return redirect('/login/?next=%s' % request.path)
# ...
  • user_passes_test(test_func,login_url=None,redirect_field_name='next')[source]

    该装饰器当调用的返回值是Fasle的时候重定向。
from django.contrib.auth.decorators import user_passes_test

def email_check(user):
return user.email.endswith('@example.com') @user_passes_test(email_check)
def my_view(request):
...

对于上面的例子,email_check接收一个User对象作为参数,当其返回值是True时,允许执行下面的my_view视图,否则不允许。

user_passes_test()有两个可选的参数:login_url和redirect_field_name。前者是跳转的url后者是url参数字符串。例如:

@user_passes_test(email_check, login_url='/login/')
def my_view(request):
...
  • class UserPassesTestMixin

继承该类,重写test_func()方法:

from django.contrib.auth.mixins import UserPassesTestMixin

class MyView(UserPassesTestMixin, View):

    def test_func(self):
return self.request.user.email.endswith('@example.com')

也可以重写get_test_func()方法,指定自定义的名称用于替代默认的test_func。

权限需求装饰器

permission_required(perm, login_url=None, raise_exception=False)[source]

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote')
def my_view(request):
...

类似has_perm()方法。权限的格式是<app label>.<permission codename>

可选的longin_url参数:

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote', login_url='/loginpage/')
def my_view(request):
...

raise_exception参数如果给予,装饰器会抛出PermissionDenied异常,并且用403页面代替重定向的登陆页面。例如:

from django.contrib.auth.decorators import login_required, permission_required

@login_required
@permission_required('polls.can_vote', raise_exception=True)
def my_view(request):
...

PermissionRequiredMixin类

同上面的loginrequiredmixin类似。

from django.contrib.auth.mixins import PermissionRequiredMixin

class MyView(PermissionRequiredMixin, View):
permission_required = 'polls.can_vote'
# Or multiple of permissions:
permission_required = ('polls.can_open', 'polls.can_edit')

可以自定义重写get_permission_required()和has_permission()方法

2.3.4 在基于类的视图中重定向未授权的请求

class AccessMixin:

  • login_url

    get_login_url()方法的默认回调函数。

  • permission_denied_message

    拒绝访问的提示信息。默认是空字符串。

  • redirect_field_name

    get_redirect_field_name()的返回值. 默认是"next".

  • raise_exception

    抛出异常。默认为False。

  • get_login_url()

  • get_permission_denied_message()

  • get_redirect_field_name()

  • handle_no_permission()¶

2.3.5 认证视图

Django没有为认证视图提供默认的模板,你需要自己创建。

使用视图

有很多种办法实现这些视图,最简单的是使用Django提供的django.contrib.auth.urls,将它添加到URLconf文件中:

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

这就相当于添加了下面的URL模式:

^login/$ [name='login']
^logout/$ [name='logout']
^password_change/$ [name='password_change']
^password_change/done/$ [name='password_change_done']
^password_reset/$ [name='password_reset']
^password_reset/done/$ [name='password_reset_done']
^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm']
^reset/done/$ [name='password_reset_complete']

其中,方括号里的是url的别名。

当然,也可以使用自定义的URL,例如:

from django.contrib.auth import views as auth_views

urlpatterns = [

url('^change-password/$', auth_views.password_change),

]

这些views有一些可选的参数。例如template_name,用于指定视图需要使用的html模板,看下面的例子:

urlpatterns = [
url(
'^change-password/$', auth_views.password_change,
{'template_name': 'change-password.html'}
),
]

所有的这类views都返回一个TemplateResponse实例,对于自定义views可以将Django提供的view封装起来使用,例如:

from django.contrib.auth import views

def change_password(request):
template_response = views.password_change(request)
# Do something with `template_response`
return template_response

所有的认证视图

下面是django.contrib.auth模块包含的所有视图:

login(request, template_name=registration/login.html, redirect_field_name='next', authentication_form=AuthenticationForm, current_app=None, extra_context=None, redirect_authenticated_user=False)

登录视图

URL name:login (该视图对应的访问地址,下同)

可选参数:

template_name: 登录页面html文件名。默认为registration/login.html。

redirect_field_name: 用于登录URL路径的参数关键字,默认是“next”。

authentication_form:用于认证的调用,默认是AuthenticationForm。

current_app: 2.0版本中将被移除,用request.current_app代替。

extra_context: 额外的数据字典

redirect_authenticated_user:一个布尔值,用于控制已登陆用户是否可以访问登录页面。默认是False。

django.contrib.auth.views.login视图的工作机制是:

使用GET请求时,显示一个登陆表单,用户可以输入登录信息。

使用POST请求时,携带用户提供的登陆信息,进行用户验证。如果验证成功,重定向到next参数指定的url地址(如果未指定next参数,则使用settings.LOGIN_REDIRECT_URL中配置的地址,该地址默认为/accounts/profile/),如果不成功,继续显示表单页面。

Django不提供registration/login.html模板文件,需要自己编写。该模板有4个环境变量:

  1. form:一个表示AuthenticationForm的Form对象
  2. next:登录成功后重定向的url地址
  3. site:当前的Site,根据SITE_ID设置。如果没有安装site框架,则被设置为一个RequestSite的实例,它将从HttpRequest中导出site名和域名。
  4. site_name:site.name的别名。如果没安装site框架,它将被设置为request.META['SERVER_NAME']的值。

也可以不使用默认的registration/login.html模板,而是指定别的模板,使用template_name参数,如下:

url(r'^accounts/login/$', auth_views.login, {'template_name': 'myapp/login.html'}),

这里有一个registration/login.html模板的简单例子(假定你已经有了base.html文件)。

{% extends "base.html" %}

{% block content %}

{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %} {% if next %}
{% if user.is_authenticated %}
<p>Your account doesn't have access to this page. To proceed,
please login with an account that has access.</p>
{% else %}
<p>Please login to see this page.</p>
{% endif %}
{% endif %} <form method="post" action="{% url 'login' %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table> <input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form> {# Assumes you setup the password_reset view in your URLconf #}
<p><a href="{% url 'password_reset' %}">Lost password?</a></p> {% endblock %}

如果使用自定义认证系统,可以通过authentication_form参数,指定你自定义的认证form显示在登录页面中。这个form必须接受一个request关键字参数在它的__init__方法中,并且提供一个get_user()方法用于返回通过认证的user对象。

logout(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name='next', current_app=None, extra_context=None)

注销视图

URL name: logout

可选参数:

  • next_page: 注销后跳转的页面。默认是settings.LOGOUT_REDIRECT_URL。
  • template_name: 注销后跳转的页面html文件.默认是registration/logged_out.html
  • redirect_field_name: 同上
  • current_app: 同上
  • extra_context:同上

模板变量:

  • title:字符串“Logged out”
  • site:同上
  • site_name:同上
logout_then_login(request, login_url=None, current_app=None, extra_context=None)

注销用户,并返回登录页面。

URL name:未设置

可选参数:

  • login_url:同上
  • current_app: 同上
  • extra_context:同上
password_change(request, template_name='registration/password_change_form.html', post_change_redirect=None, password_change_form=PasswordChangeForm, current_app=None, extra_context=None)¶

用户修改密码的页面

URL name:password_change

可选参数:

  • template_name:用于显示修改密码表单的页面文件。默认是registration/password_change_form.html。
  • post_change_redirect:成功修改后跳转的url
  • password_change_form:自定义的“change password”表单,它必须接收一个user关键字参数。默认为PasswordChangeForm。
  • current_app: 同上
  • extra_context:同上

模板变量:

  • form:修改密码的表单
password_change_done(request, template_name='registration/password_change_done.html', current_app=None, extra_context=None)

用户修改完密码后的页面。

URL name: password_change_done

可选参数:

  • template_name:用于显示修改密码表单的页面文件。默认是registration/password_change_form.html。
  • current_app: 同上
  • extra_context:同上
password_reset(request, template_name='registration/password_reset_form.html', email_template_name='registration/password_reset_email.html', subject_template_name='registration/password_reset_subject.txt', password_reset_form=PasswordResetForm, token_generator=default_token_generator, post_reset_redirect=None, from_email=None, current_app=None, extra_context=None, html_email_template_name=None, extra_email_context=None)¶

生成一个一次性的连接,并将该连接发送到用户注册的邮箱地址,用户通过改地址重置他的密码。

为了防止潜在的攻击,如果提供的邮件地址在系统中不存在,视图不会发送邮件,用户也不会受到任何的错误信息提示。如果想要提供错误信息的话,继承PasswordResetForm类,并使用password_reset_form参数。

URL name: password_reset

可选参数:

  • template_name: 同上。默认是registration/password_reset_form.html。
  • email_template_name:发送携带重置密码连接的邮件的页面。默认是registration/password_reset_email.html。
  • subject_template_name:邮件的主题,默认是registration/password_reset_subject.txt。
  • password_reset_form: 同上
  • token_generator:检查一次性连接的类的实例。默认是default_token_generator,它是django.contrib.auth.tokens.PasswordResetTokenGenerator的一个实例。
  • post_reset_redirect: 同上
  • from_email: 发件人地址。默认是DEFAULT_FROM_EMAIL。
  • current_app: 同上
  • extra_context:同上
  • html_email_template_name: 默认情况下HTML email不发送。
  • extra_email_context: email模板中额外的数据字典。

模板变量:

  • form:同上

email模板变量:

  • email:user.email的别名
  • user:当前user。只有有效的用户才可以重置他们的密码(User.is_active is True)。
  • site_name:同上
  • domain:site.domain的别名。如果没有安装site框架,则为request.get_host()。
  • protocol: http或者https协议
  • uid: 用户的主键,基于64位。
  • token: 用于检查重置连接合法性的令牌

一个简单的registration/password_reset_email.html文件范例:

Someone asked for password reset for email {{ email }}. Follow the link below:
{{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
password_reset_done(request, template_name='registration/password_reset_done.html', current_app=None, extra_context=None)

密码重置后的跳转页面

URL name: password_reset_done

可选参数:

  • template_name: 同上。默认是registration/password_reset_done.html。
  • current_app: 同上
  • extra_context:同上
password_reset_confirm(request, uidb64=None, token=None, template_name='registration/password_reset_confirm.html', token_generator=default_token_generator, set_password_form=SetPasswordForm, post_reset_redirect=None, current_app=None, extra_context=None)

显示一个输入新密码的表单

URL name: password_reset_confirm

可选参数:

  • uidb64: 同上,默认为None。
  • token: 检查密码是否合法的令牌,默认为None.
  • template_name: 同上,默认为registration/password_reset_confirm.html.
  • token_generator: 同上
  • set_password_form: 用于设置密码的表单。默认为SetPasswordForm。
  • post_reset_redirect: 同上,默认为None。
  • current_app: 同上
  • extra_context: 同上

模板变量:

  • form: 同上
  • validlink: 布尔值。链接合法则为True。
password_reset_complete(request, template_name='registration/password_reset_complete.html', current_app=None, extra_context=None)

提示用户密码已经成功修改

URL name: password_reset_complete

可选参数:

  • template_name: 同上,默认为registration/password_reset_confirm.html.
  • current_app: 同上
  • extra_context: 同上

2.3.6 有用的函数

redirect_to_login(next, login_url=None, redirect_field_name='next')

重定向到登录页面,登录成功后跳转到指定的url。

必须参数:next,登录成功后跳转的url

可选参数:longin_url和redirect_field_name

2.3.7 内置表单

如果你不想使用内置的视图,但又不想编写表单,认证系统提供了内置的表单供你直接使用,它们位于django.contrib.auth.forms。

class AdminPasswordChangeForm

admin中用于修改用户密码的表单。user是它的第一位置参数。

class AuthenticationForm

登录表单,request是它的第一位置参数。

confirm_login_allowed(user):默认情况下,它拒绝is_active标识为False的用户。要修改这个规则,你需要继承AuthenticationForm类,并重写confirm_login_allowed()方法。如果给予的用户没有登录,它应该抛出一个ValidationError异常。

例如,允许所有用户登录,不管它是否active:

from django.contrib.auth.forms import AuthenticationForm

class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm):
def confirm_login_allowed(self, user):
pass

或者只允许某些状态的用户登录:

class PickyAuthenticationForm(AuthenticationForm):
def confirm_login_allowed(self, user):
if not user.is_active:
raise forms.ValidationError(
_("This account is inactive."),
code='inactive',
)
if user.username.startswith('b'):
raise forms.ValidationError(
_("Sorry, accounts starting with 'b' aren't welcome here."),
code='no_b_users',
)

class PasswordChangeForm

用户修改自己密码的表单

class PasswordResetForm

一个表单,用于生成和发送带有一次性连接的邮件,帮助用户重置密码。

send_email(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)

发送邮件的方法。

参数:

  • subject_template_name – 主题模板
  • email_template_name – 邮件主题模板
  • context – 传递给subject_template, email_template和html_email_template 的数据
  • from_email – 发件人
  • to_email – 收件人
  • html_email_template_name

class SetPasswordForm

设置密码的表单

class UserChangeForm

admin中修改用户信息和权限的表单

class UserCreationForm

创建新用户的ModelForm。它有3个字段,username、password1和password2.

2.3.8 模板中的认证数据

用户

渲染一个RequestContext模板时,当前已登陆的用户,或者一个User实例,或者一个 AnonymousUser实例,都被保存在模板的变量{{ user }}中。例如:

{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}

如果不是使用的RequestContext,这些变量将不可用。

权限

当前登陆用户的权限保存在模板变量 {{ perms }}中。它是一个django.contrib.auth.context_processors.PermWrapper的实例。

对于{{ perms }}对象,单级属性查询相当于User.has_module_perms的功能。例如:

{{ perms.foo }},如果登陆用户有任何foo的权限,该变量就等于True。

双级属性查询相当于User.has_perm。例如:{{ perms.foo.can_vote }}

因此,你可以在if语句中使用它们,如下面的例子所示:

{% if perms.foo %}
<p>You have permission to do something in the foo app.</p>
{% if perms.foo.can_vote %}
<p>You can vote!</p>
{% endif %}
{% if perms.foo.can_drive %}
<p>You can drive!</p>
{% endif %}
{% else %}
<p>You don't have permission to do anything in the foo app.</p>
{% endif %}

还可以使用关键字“in”,进行范围判断:

{% if 'foo' in perms %}
{% if 'foo.can_vote' in perms %}
<p>In lookup works, too.</p>
{% endif %}
{% endif %}

2.4 在admin站点中管理用户

当django.contrib.admin与django.contrib.auth都被安装时,可以在admin站点中方便的对用户、组和权限进行管理。

Authentication of Django的更多相关文章

  1. User authentication in Django(用户认证)

    一,概述: auth 系统包括: 1)Users 2)Permissions: Binary (yes/no) flags designating whether a user may perform ...

  2. 玩儿了一下django User authentication

    五一在家,VPN不能链接了,而项目在本地run的过程中,又需要链接公司的SSO server才能login.下雨,不想去公司,又不得不在家做task,只能想办法避开SSO login,以前知道djan ...

  3. Writing your first Django app, part 1(转)

    Let’s learn by example. Throughout this tutorial, we’ll walk you through the creation of a basic pol ...

  4. Django REST framework+Vue 打造生鲜超市(四)

    五.商品列表页 5.1.django的view实现商品列表页 (1)goods/view_base.py 在goods文件夹下面新建view_base.py,为了区分django和django res ...

  5. python框架之Django(14)-rest_framework模块

    APIView django原生View post请求 from django.shortcuts import render, HttpResponse from django import vie ...

  6. Django手册

    Django教程 Python一直是我最喜欢的语言,在Django和Tornado之间我选择了前者,没有特别的原因,网上人云亦云的,肯定不会有一方离另一方差很远,我就直接去看了看Github上两个项目 ...

  7. Django 2.0.1 官方文档翻译: 文档目录 (Page 1)

    Django documentation contents 翻译完成后会做标记. 文档按照官方提供的内容一页一页的进行翻译,有些内容涉及到其他节的内容,会慢慢补上.所有的翻译内容按自己的理解来写,尽量 ...

  8. 二、django rest_framework源码之认证流程剖析

    1 绪言 上一篇中讲了django rest_framework总体流程,整个流程中最关键的一步就是执行dispatch方法.在dispatch方法中,在调用了一个initial方法,所有的认证.权限 ...

  9. 【Python】Django用户、认证、鉴权模块使用

    此文是总结Django官方网站里面的Document的文章 User authentication in Django http://www.djangoproject.com/documentati ...

随机推荐

  1. 执行CSRF令牌所有形式使用POST方法

    从而在并未授权的情况下执行在权限保护之下的操作,有很大的危害性. php CSRF Guardfunction csrfguard_generate_token($unique_form_name){ ...

  2. “眉毛导航”——SiteMapPath控件的使用(ASP.NET)

    今天做网站的时候,用到了SiteMapPath控件,我把使用方法记录下来,以便日后查阅以及帮助新手朋友们. SiteMapPath”会显示一个导航路径(也称为痕迹导航或眉毛导航),此路径为用户显示当前 ...

  3. Delphi中stringlist分割字符串的用法

    Delphi中stringlist分割字符串的用法 TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 1.CommaT ...

  4. .NET Core 跨平台发布(dotnet publish)

    .NET Core 跨平台发布(dotnet publish) ,无需安装.NET Core SDK,就可以运行. 前面讲解了.NET Core 的VSCode 开发.现在来讲讲发布(dotnet p ...

  5. python自动化测试(4)-使用第三方python库技术实现

    python自动化测试(4)-使用第三方python库技术实现 1   概述 关于测试的方法论,都是建立在之前的文章里面提到的观点: 功能测试不建议做自动化 接口测试性价比最高 接口测试可以做自动化 ...

  6. Step by step Dynamics CRM 2013安装

    原创地址:http://www.cnblogs.com/jfzhu/p/4008391.html 转载请注明出处   SQL Server可以与CRM装在同一台计算机上,也可安装在不同的计算机上.演示 ...

  7. 每天一个linux命令(23):Linux 目录结构

    对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面 ...

  8. 支持向量机(SVM)复习总结

    摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 其基本模型定义为特征空间上的间隔最大的线性分类器,即支持向量机的学习策略 ...

  9. sql的行转列(PIVOT)与列转行(UNPIVOT)

    在做数据统计的时候,行转列,列转行是经常碰到的问题.case when方式太麻烦了,而且可扩展性不强,可以使用 PIVOT,UNPIVOT比较快速实现行转列,列转行,而且可扩展性强 一.行转列 1.测 ...

  10. java继承、抽象和接口

    package zdbExtends;public class Grandparent {        public Grandparent(){                System.out ...