<学习笔记>从零开始自学Python-之-web应用框架Django( 十一)用户系统和身份验证

news2024/11/24 22:50:08

用户系统是现代网站的重要组成部分,对用户进行分组权限管理是非常必要的。

Django内置了一套用户和身份验证系统,不用太多代码开发就可以使用这个系统。

Django 的身份验证系统包括:

• 用户

• 权限:二元(是或否)旗标,指明用户是否能执行特定的任务

• 分组:把标注和权限赋予多个用户的通用方式

• 可配置的密码哈希系统

• 管理身份验证和权限核准的表单

• 登录用户或限制内容的视图工具

• 可更换的后端系统

Django 的身份验证系统十分通用,没有提供 Web 身份验证系统中某些常用的功能。

某些常用功能通过第三 方包实现:

• 密码强度检查

• 登录尝试次数限制

• 通过第三方验证身份(如 OAuth)

1、User对象

User 对象是这个身份验证系统的核心,通常用于标识与网站交互的人,还用于限制访问、记录用户资料,以 及把内容与创建人关联起来,等等。

在 Django 的身份验证框架中,只有一个用户类存在,因此 superusers 或管理后台的 staff 用户只是设定了特殊属性的用户对象,而不是分属不同类的用户对象。

默认用户主要有 下面几个属性:

• username

• password

• email

• first_name

• last_name

1.1 创建超级用户

超级用户使用 createsuperuser 命令创建:

python manage.py createsuperuser --username=teacherWang --email=wangchongyang@126.com

上述命令会提示你输入密码。输入密码后,立即创建指定的超级用户。

如果没有指定 --username 或 --email 选项,会提示你输入这两个值。

Email address: wangchongyang@126.com
Password: 
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
Bypass password validation and create user anyway? [y/N]: n
Password: 
Password (again):
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

最终看到 Superuser created successfully说明创建成功了。

1.2 创建用户

创建和管理用户最简单、最不易出错的方式是使用 Django 管理后台。

管理后台的使用我们在第七章((1条消息) <学习笔记>从零开始自学Python-之-web应用框架Django( 七)Django管理后台_阿尔法羊的博客-CSDN博客)详细讲过了

当然也可以用Django内置的辅助函数create_user()来实现同样的功能

from django.contrib.auth.models import User 
user = User.objects.create_user('teacherWang', 'wangchongyang@126.com', 'password') 
# 此时,user 是一个 User 对象,而且已经保存到数据库中 
# 如果想修改其他字段的值,可以继续修改属性 
user.last_name = 'wang' 
user.save()

1.3 在 Web 请求中验证身份

Django 使用会话和中间件把身份验证系统插入 request 对象,为每个请求提供 request.user 属性,表示当前用户。如果未登陆,这个属性的值是一个 AnonymousUser 实例,否则是是一个 User 实例。

这两种情况可以使 用 is_authenticated() 方法区分,例如:

if request.user.is_authenticated(): 
    # 处理通过身份验证的用户 

else: 
    # 处理匿名用户

2、在视图中操作身份验证

2.1 登录与退出

2.1.1 在视图中使用 login() 登录用户。

它的参数是一个 HttpRequest 对象和一个 User 对象。login() 使用 Django 的会话框架把用户的 ID 保存到会话中。注意,匿名期间设定的会话数据在用户登录后依然存在。

下述示例 展示 authenticate() 和 login() 的用法:

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: 
        if user.is_active: 
            login(request, user) 
            # 重定向到成功登录页面 
        else: 
            # 返回“账户未激活”错误消息 
    else: 
        # 返回“无效登录”错误消息

注意:自己动手登录用户时,必须在 login() 之前调用 authenticate()。authenticate() 在 User 对象 上设定一个属性,指明成功验证用户身份的是哪个身份验证后端,而登录过程中需要使用这个信息。如果直接登录从数据库中检索的用户对象,Django 会报错。

2.1.2 在视图中使用logout()退出

在视图中退出通过 login() 登录的用户使用 logout()。这个函数的参数是一个 HttpRequest 对象,而且没有返回值。

例如:

from django.contrib.auth import logout 
def logout_view(request): 
    logout(request) 
    # 重定向到成功退出页面 

注意,如果用户未登录,logout() 函数不报错。调用 logout() 函数后,当前请求的会话数据完全清除,所有 数据将被删除。这样能避免其他人在登录的 Web 浏览器中访问用户之前的会话数据。 如果想让会话中的数据在退出后依然可用,调用 logout() 函数之后再把数据存入会话。

2.2 限制已登录用户的访问

2.2.1 直接方式

限制访问页面简单直接的方式是检查 request.user.is_authenticated(),如果未通过,可以重定向到登录页面:

from django.shortcuts import redirect 
def my_view(request): 
    if not request.user.is_authenticated(): 
        return redirect('/login/?next=%s' % request.path) 
        
# ... 也可以显示一个错误消息: 
from django.shortcuts import render 
def my_view(request): 
    if not request.user.is_authenticated():
        return render(request, 'books/login_error.html') 

2.2.2 装饰器

也可以使用便利的 login_required() 装饰器:

from django.contrib.auth.decorators import login_required 

@login_required 
def my_view(request): 
    ...

login_required() 的作用如下:

• 如果用户未登录,重定向到 LOGIN_URL,并把当前绝对路径添加到查询字符串中。

例如:/accounts/ login/?next=/reviews/3/。

• 如果用户已登录,正常执行视图。视图代码可以放心假定用户已登录。

默认,成功通过身份验证后重定向的目标路径存储在名为 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 提供了值,可能还要定制登录模板,因为模板上下文中存储重定向路径的变量名是 redirect_field_name 的值,而不再是默认的 next。

login_required() 还有个可选的 login_url 参 数。例如:

from django.contrib.auth.decorators import login_required
 
@login_required(login_url='/accounts/login/') 
def my_view(request): 
    ...

注意,如果不指定 login_url 参数,要确保把 LOGIN_URL 设为正确的登录视图。例如,使用默认配置时,要 把下述代码添加到 URL 配置中:

from django.contrib.auth import views as auth_views 

url(r'^accounts/login/$', auth_views.login),

LOGIN_URL 的值还可以是视图函数名称或具名 URL 模式。这样,无需修改设置就可以在 URL 配置中自由映射登录视图。

2.3 permission_required 装饰器

检查用户有没有特定权限是比较常见的任务。鉴于此,Django 提供了一种简便的方式——permission_required() 装饰器:

from django.contrib.auth.decorators import permission_required @permission_required('reviews.can_vote') 
def my_view(request): 
    ...

与 has_perm() 方法一样,参数名称的形式为“.”(例如,reviews.can_vote 是 reviews 应用中某个模型定义的权限)。这个装饰器的参数也可以是一个权限列表。注意,permission_required() 也有可选的 login_url 参数。例如:

from django.contrib.auth.decorators import permission_required @permission_required('reviews.can_vote', login_url='/loginpage/') 
def my_view(request):
    ...

与 login_required() 装饰器一样,login_url 的默认值是 LOGIN_URL。如果指定了 raise_exception 参数,这 个装饰器不会重定向到登录页面,而是抛出 PermissionDenied 异常,显示 403(HTTP Forbidden)视图。

2.4、身份验证视图

Django 为登录、退出和密码管理提供了视图。这些视图使用 auth 包中内置的表单,不过也可以传入自己编写的视图。Django 没有为身份验证视图提供默认的模板,不过下文将说明各个视图的模板上下文。

在项目中使用这些视图要实现不同的方法,不过最简单也是最常见的做法是把 django.contrib.auth.urls 提 供的 URL 配置添加到项目的 URL 配置中。例如:

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

这样,各个视图在默认的 URL 上(后文详述)。 这些内置的视图都返回一个 TemplateResponse 实例,这样便于在渲染之前定制响应数据。多数内置的身份验 证视图提供了 URL 名称,易于引用。

2.4.1 login 视图

登录用户。

默认 URL:/login/。

可选参数:

• template_name:这个视图使用的模板名称。默认为 registration/login.html。

• redirect_field_name:GET 参数中指定登录后重定向 URL 的字段名称。默认为 next。

• authentication_form:验证身份的可调用对象(通常是一个表单类)。默认为 AuthenticationForm。

• current_app:一个提示,指明当前视图所在的应用。

• extra_context:一个字典,包含额外的上下文数据,随默认的上下文数据一起传给模板。 login 视图的作用如下:

• 如果通过 GET 调用,显示登录表单,其目标地址与当前 URL 一样。稍后详述。

• 如果通过 POST 调用,发送用户提交的凭据,尝试登录用户。如果登录成功,重定向到 next 指定的 URL。如果没有 next,重定向到 LOGIN_REDIRECT_URL(默认为 /accounts/profile/)。如果登录失败,重新显示登录表单。 登录视图的模板由你提供,模板文件默认名为 registration/login.html。

模板上下文:

• form:表示 AuthenticationForm 的 Form 对象。

• next:成功登录后重定向的目标 URL。自身可能也包含查询字符串。

• site:当前 Site,根据 SITE_ID 设置确定。如果未安装网站框架,其值默认为 RequestSite 实例,从 当前 HttpRequest 对象中获取网站名称和域名。

• site_name:site.name 的别名。如果未安装网站框架,其值为 request.META['SERVER_NAME'] 的值。 如果不想把模板命名为 registration/login.html,可以为 URL 配置提供额外的参数,设定 template_name 参数。

2.4.2 logout 视图

退出用户。

默认 URL:/logout/

可选的参数:

• next_page:退出后重定向的目标 URL。

• template_name:一个模板全名,在用户退出后显示。如果未提供这个参数,默认为 registration/ logged_out.html。

• redirect_field_name:GET 参数中指定退出后重定向 URL 的字段名称。默认为 next。如果提供这个参数,next_page 将被覆盖。

• current_app:一个提示,指明当前视图所在的应用。

• extra_context:一个字典,包含额外的上下文数据,随默认的上下文数据一起传给模板。

模板上下文:

• title:本地化之后的字符串“Logged out”。

• site:当前 Site,根据 SITE_ID 设置确定。如果未安装网站框架,其值默认为 RequestSite 实例,从 当前 HttpRequest 对象中获取网站名称和域名。

• site_name:site.name 的别名。如果未安装网站框架,其值为 request.META['SERVER_NAME'] 的值。

2.4.3 logout_then_login 视图

退出用户,然后重定向到登录页面。

默认 URL:未提供。

可选的参数:

• login_url:重定向到的登录页面的 URL。如果未提供,默认为 LOGIN_URL。

• current_app:一个提示,指明当前视图所在的应用。

• extra_context:一个字典,包含额外的上下文数据,随默认的上下文数据一起传给模板。

2.5 内置的表单

如果不想使用内置的视图,也不想为这些功能编写表单,可以使用身份验证系统在 django.contrib.auth.forms 中内置的几个表单(表 11-1)。 这些内置的表单对用户模型有些假设,如果自定义了用户模型,可能要自己动手为身份验证系统编写表单。

Django 内置的身份验证表单
表单名说明
AdminPasswordChangeForm在管理后台中用于修改用户密码的表单。第一个位置参数是用户对象。
AuthenticationForm登录表单。请求对象是第一个位置参数,存储在表单中,供子类使用。
PasswordChangeForm修改密码的表单。
PasswordResetForm用于生成并发送带有重设密码链接的电子邮件。
SetPasswordForm让用户修改密码的表单,无需输入旧密码。
UserChangeForm在管理后台中用于修改用户信息和权限的表单。
UserCreationForm创建新用户的表单。

2.6 模板中的身份验证数据

使用 RequestContext 时,当前登录用户及其权限可通过模板上下文访问。

2.6.1 用户

渲染模板的 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,这个模板上下文变量不可用。

2.6.2 权限

当前登录用户的权限存储在模板变量 {{ perms }} 中。它的值是 django.contrib.auth.context_processors.PermWrapper 的一个实例,对模板友好。在 {{ perms }} 对象中,单属性查找由 User.has_module_perms 代理。只要当前登录用户在 foo 应用中有权限,下述示例就返回 True:

{{ perms.foo }}

两层属性查找由 User.has_perm 代理。如果当前登录用户有 foo.can_vote 权限,下述示例返回 True:

{{ 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 %}

此外,还可以使用 {% if in %} 语句检查权限。

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

3、案例:自己动手做一个网站用户系统

基于我们前面已经做好的网站,我们现在做一个简单的用户登录和注册系统,然后设置权限

3.1 登录系统

先写一个简单的登录页面login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<div class="container" style="margin-top: 100px">
    <div class="row">
        <div>
            <div>
                <div>
                    <h3>登录</h3>
                </div>
                <div>
                    <form action="" method="post" novalidate>
                        {% csrf_token %}
 
{#                        方法一: 写出form表单中的指定字段 #}
{#                        {{ login_form.username.label_tag }}:#}
{#                        {{ login_form.username }}#}
{#                        <p>{{ login_form.errors.username.0 }}</p>#}
{#                        {{ login_form.password.label_tag }}:#}
{#                        {{ login_form.password }}#}
{#                        <p>{{ login_form.errors.password.0 }}</p>#}
{#                        <div>{{ login_form.non_field_errors }}</div>#}
 
{#                        方法二: 遍历出form表单中的所有字段 #}
                        {% for field in login_form %}
                            {{ field.label_tag }}
                            {{ field }}
                            <p>{{ field.errors.as_text }}</p>
                        {% endfor %}
{#                        此处错误信息会返回clean联合校验,也就是非单个字段校验的错误信息#}
                        <span>{{ login_form.non_field_errors }}</span>
 
                        <input type="submit" value="登录" class="btn">
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
<br>
<div>
    <a href="/register">注册</a>
</div>
</body>
</html>

然后我们在forms.py里面创建一个LoginForm类,用于接收前端表单输入的数据,并实现验证

from django import forms
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
 
 
class LoginForm(forms.Form):
    username = forms.CharField(
        label="用户名",
        min_length=3,
        widget=forms.TextInput(attrs={"class": "form-control", "placeholder": "请输入用户名"}),
        error_messages={
            "required": "用户名不能为空",
            "min_length": "用户名最小长度为3位",
        },
    )
    password = forms.CharField(
        label="密码",
        min_length=6,
        error_messages={
            "min_length": "密码最小长度为6位",
            "required": "密码不能为空",
        },
        widget=forms.PasswordInput(attrs={"class": "form-control", "placeholder": "请输入密码"}),
    )
 
    def clean(self):
        username = self.cleaned_data.get("username", "")
        password = self.cleaned_data.get("password", "")
        user = authenticate(username=username, password=password)
        if not user:
            raise forms.ValidationError("用户名或密码错误")
 
        self.cleaned_data["user"] = user
        return self.cleaned_data

然后在views.py 里面写好一个登录的函数

def user_login(request):
    if request.method == "GET":
        username = request.GET.get("username")
        login_form = LoginForm()
        return render(request, "login.html", context={"login_form": login_form})
    elif request.method == "POST":
        login_form = LoginForm(request.POST)
        if login_form.is_valid():
            # 注意:验证用户名和密码是否正确放到forms中去验证了
            # login(request, request.user)  # 此处不能使用request.user,因为他还没有验证,是匿名用户
            # 所以需要在form中校验通过后传递过来user
            login(request, login_form.cleaned_data["user"])
            user = request.POST["username"]
            next = request.GET.get("next", reverse("index"))
            return redirect(next,{'user':user})
        else:
            return render(request, "login.html", {"login_form": login_form})

如果从form类返回的验证正确,就跳转到指定网页,这里指定到 index 页面,注意这里这个 index 是 路由的名字(name,就是设置path时候指定的name)。

最后在urls.py 里面加上路由

path('login/',user_login,name="login"),

我们访问http://127.0.0.1:8000/login

 因为没有加上css,界面看上去比较朴素,但是已经可以使用了

3.2 注册系统

当然这时候我们只有一个前面创建的超级用户,要想让普通用户注册使用,还要做一个注册系统

一样,先写好前端的表单页面 register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
<div class="container" style="margin-top: 100px">
    <div class="row">
        <div>
            <div>
                <div>
                    <h3>注册</h3>
                </div>
                <div>
                    <form action="" method="post" novalidate>
 
                        {% csrf_token %}
                        {% for field in register_form %}
                            {{ field.label_tag }}
                            {{ field }}
                            <p>{{ field.errors.as_text }}</p>
                        {% endfor %}
                        <span>{{ register_form.non_field_errors }}</span>
                        <input type="submit" value="注册">
 
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

在forms.py里面写一个注册用的 RegisterForm类

class RegisterForm(LoginForm):
    password_again = forms.CharField(
        label="确认密码",
        min_length=6,
        error_messages={
            "required": "确认密码不能为空",
            "min_length": "密码最小长度为6位",
        },
        widget=forms.PasswordInput(attrs={"class": "form-control", "placeholder": "确认密码"}),
    )
    email = forms.EmailField(
        label="邮箱",
        required=False,
        error_messages={
            "required": "密码不能为空",
        },
        widget=forms.EmailInput(attrs={"class": "form-control", "placeholder": "请输入邮箱"})
    )
 
    def clean_username(self):
        username = self.cleaned_data["username"]
        if User.objects.filter(username=username).exists():
            raise forms.ValidationError("用户名已存在")
        return username
 
    def clean_email(self):
        email = self.cleaned_data["email"]
        if email and User.objects.filter(email=email).exists():
            raise forms.ValidationError("邮箱已存在")
 
        return email
 
    def clean(self):
        password = self.cleaned_data.get("password", "")
        password_again = self.cleaned_data.get("password_again", "")
 
        if password != password_again:
            raise forms.ValidationError("两次密码不一致,请重新输入")
 
        return self.cleaned_data

再在views.py里面 写好视图函数

def user_register(request):
    if request.method == "GET":
        register_form = RegisterForm()
        return render(request, "register.html", context={"register_form": register_form})
    elif request.method == "POST":
        register_form = RegisterForm(request.POST)
        if register_form.is_valid():
            username = register_form.cleaned_data["username"]
            password = register_form.cleaned_data["password"]
            email = register_form.cleaned_data.get("email", "")
            # 创建用户
            user = User.objects.create_user(username, email, password)
            next = request.GET.get("next", reverse("index"))
            return redirect(next)
        else:
            return render(request, "register.html", {"register_form": register_form})

最后加上路由

path('register/',user_register,name="register"),

我们访问 http://127.0.0.1:8000/register

我们注册一个名为testone的用户,登录之后可以看到, 用户名正确显示出来了

 

3.3 退出登录

 这里我们前端加了一个退出登录的功能按钮

Django内置了一个logout 函数,实现logout功能非常容易

def user_logout(request):

    logout(request)

    return redirect("login")

3.4 设置权限

既然使用了用户系统,当然对用户访问就要做些限制,我们在主页视图函数前加上装饰器,并指定如果未登录时候的跳转页面(如果不指定,默认的跳转页面是('/accounts/login/')

from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/')
def classnotice(request):
    print(request.GET)
    now=datetime.datetime.now()
    context={}
    context['student_list']=Student.objects.all().order_by('-score')
    context['teacher']='王重阳'
    context['now']=now
    
    return render(request,'class3.html',context=context,status=200)

再访问主页,就会跳转到登录页面

最后我们再来设置一下权限。比如之前我们做了一个add_student的表单,用于增加Student模型的实例。现在我们给这个功能加上权限,这样没有权限的用户就会退到登录界面

from django.contrib.auth.decorators import permission_required
@permission_required('classManage.add_student',login_url='/login/')
def add_student(request):
    if request.method == 'GET':
        student_list = addStudent()
        return render(request,'addStudent.html',{'students':student_list},status=200)
    else:
        student_list = addStudent(request.POST)
        if student_list.is_valid():
            student_list.save()
        return render(request,'addStudent.html',{'student_list':student_list},status=200)

这时候,我们用teacherWang账户登录可以访问 ‘/add_student/’,但是用testone账户访问'/add_student'就会跳转到登录界面。

我们用程序给testone账户赋予权限

from classManage.models import Student
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType

user = User.objects.get(username='testone')
permission = Permission.objects.get(codename='add_student')
user.user_permissions.add(permission)

然后再用testone账户登录,再访问http://127.0.0.1:8000/add_student

发现可以访问了

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/50864.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity游戏Mod/插件制作教程05 - 插件实例2: 简单功能实现

这一次的教程进行一个小小的功能实现&#xff0c;完整的制作一个插件。以Mirror这个游戏为例&#xff0c;插件的目标是当玩家按下空格时&#xff0c;有一定概率为玩家增加金钱&#xff0c;或者扣除玩家金钱。概率、增加的金钱、扣除的金钱都由配置文件决定。 使用dnSpy查找金钱…

【SQL】数据库事务

【SQL】数据库事务事物的ACID特性事务的状态显式事务隐式事务事务的使用举例SQL中的四种隔离级别MySQL中的隔离级别如何设置事务的隔离级别innodb默认支持事务事务是一组逻辑操作单元&#xff0c;使数据从一种状态转变到另一种状态事物的ACID特性 原子性&#xff08;atomicity…

Java搭建宝塔部署实战毕设项目springboot车险理赔管理系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套Java开发的毕业设计项目springboot车险理赔管理系统源码。 技术架构 技术框架&#xff1a;SpringBoot mybatis bootstrap jquery mysql5.7运行环境&#xff1a;jdk8 nginx1.20 tomcat9 …

QT学习笔记(六)——QT弹出对话框并在主窗口调用对话框的信息

QT弹出对话框并在主窗口调用对话框的信息&#xff0c;显示影像 最近封控&#xff0c;大部分时间都在自己学习写代码&#xff0c;有点feel 了哈&#xff0c;自己摸出来一个简单的qt 界面&#xff0c;也实现了自己想要的功能。本篇博客主要记录一下&#xff0c;如何弹出对话框&a…

[附源码]SSM计算机毕业设计疫情期间物资分派管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

@Accessors 注解作用

文章目录前言一、Accessors 源码二、Accessors 属性说明1、fluent 属性2、chain 属性3、prefix 属性前言 在最近的工作中&#xff0c;看到 Accessors(chain true) 这样的注解&#xff0c;上网查询了下&#xff0c;他是 lombok 插件包中的一个注解&#xff0c;那么它是什么意思…

如何快速实现一个颜色选择器

在做前端界面开发的时候&#xff0c;遇到需要改变颜色的需求&#xff0c;就需要使用颜色选择器。 针对这个问题&#xff0c;第一想法&#xff0c;自然是H5提供了input color&#xff0c;可以实现。但不出意外的&#xff0c;IE并不支持。而且&#xff0c;chrome的实现方式和fire…

[附源码]Python计算机毕业设计Django个人博客系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【java】输入输出流

文章目录标准输入流标准输出流字节打印流字符打印流案例--复制java文件&#xff08;文件打印流版本&#xff09;对象序列化流序列化流反序列化流serialVersionID&transientProperties作为Map集合的使用Properties作为集合的特有方法Properties与IO流相结合的方法案例--游戏…

必备模块知识——超声波传感器

一、超声波传感器 1、什么是超声波 人们能听到声音是由于物体振动产生的&#xff0c;它的频率在20HZ-20KHZ范围内&#xff0c;超过20KHZ称为超声波&#xff0c;低于20HZ的称为次声波。常用的超声波频率为几十KHZ-几十MHZ。 2、什么是超声波传感器&#xff08;常用的HC-SR04超…

基于PHP+MySQL教室预约管理系统的设计与实现

随着我国国民教育的提高,大学生的数量一直在不断的增加,根据网络资料的查询,发现2012年的大学生人数为600万,这是一个不小的数量,说明了我国教育的进步是巨大的。但是问题也随之产生,每年如此多的大学生就需要大学不断的扩建,可是还是不能满足如此多的学生对教室的使用,所以如何…

【学习笔记】深度学习入门:基于Python的理论与实现-与学习相关的技巧

CONTENTS六、与学习相关的技巧6.1 参数的更新6.2 权重的初始值6.3 Batch Normalization6.4 正则化6.5 超参数的验证六、与学习相关的技巧 6.1 参数的更新 神经网络的学习的目的是找到使损失函数的值尽可能小的参数。这是寻找最优参数的问题&#xff0c;解决这个问题的过程称为…

YOLOv7(目标检测)数据集、训练、推理过程

一、环境安装&#xff1a; pip install -r requirements.txt pip install torch1.8.2cu111 torchvision0.9.2cu111 torchaudio0.8.2 -f https://download.pytorch.org/whl/lts/1.8/torch_lts.html -i https://pypi.tuna.tsinghua.edu.cn/simple二、修改配置环境 直接看下面…

[附源码]SSM计算机毕业设计血库管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

JavaScript -- 03. 运算符介绍

文章目录运算符1 算数运算符1.1 基础符号1.2 自动类型转换2 赋值运算符3 一元4 自增和自减4.1 自增运算符4.2 -- 自减运算符5 逻辑运算符5.1 逻辑非5.2 逻辑与5.3 逻辑或6 关系运算符7 相等运算符7.1 7.2 7.3 !7.4 !8 条件运算符&#xff08;三元表达式&#xff09;9 运算符的…

专栏 | 解析“全闪对象存储”(三)

在上一节“对象存储的使用场景”中&#xff0c;我们介绍了对象存储在大规模非结构化数据存储、云存储、大数据和数据湖等场景的使用。 那么&#xff0c;优秀对象存储产品是怎样的&#xff1f;如何设计、实现&#xff1f;本节&#xff0c;我们来分析、探讨这些问题。 通过前两…

推荐系统-召回-概述(四):热门推荐

无论个性化多么重要&#xff0c;热门推荐都是推荐系统里不可或缺的一部分。其一、根据“二八定律”&#xff0c;电商系统中的20%的头部内容被80%的流量消费&#xff0c;因此&#xff0c;在产品早期&#xff0c;仅仅推荐热门内容&#xff0c;实施成本不高&#xff0c;且效果也会…

【Android App】利用腾讯地图获取地点信息和规划导航线路讲解及实战(附源码和演示视频 超详细必看)

需要源码请点赞关注收藏后评论区留言~~~ 一、获取地点信息 至于如何集成腾讯地图和调用腾讯地图接口此处不再赘述&#xff0c;有需要请参见我之前的博客 腾讯地图用来搜索POI地点的工具是TencentSearch&#xff0c;通过它查询POI主要分为下列四个步骤&#xff1a; &#xff0…

MySQL---基于CentOS7

在Linux上安装MySQL 本章简单阐述一下&#xff0c;mysq基于centos7的安装步骤 在VM上模拟安装 MySQL版本为&#xff1a;8.0.30 文章目录在Linux上安装MySQL1. MySQL下载卸载MariaDB查看版本卸载2.安装解压mysql压缩包重命名创建用户和组修改权限编写配置文件配置PATH变量初始化…

基于PHP+MySQL集训队员管理系统的设计与实现

ACM是国际大学生程序设计竞赛,这是一个展示大学生风采的平台,但是在ACM报名的时候可能会有很多的队员,管理员对队员的管理是一个繁琐且复杂的过程,通常的管理模式是手工进行管理,这在很大程度上有一些弊端,为了改成这一现状需要一个对应的管理系统出现。 本设计尝试用PHP开发一…