当前位置: 首页 > news >正文

深入Django:用户认证与权限控制实战指南


title: 深入Django:用户认证与权限控制实战指南
date: 2024/5/7 18:50:33
updated: 2024/5/7 18:50:33
categories:

  • 后端开发

tags:

  • Auth
  • Decorators
  • Permissions
  • Guardian
  • RESTAuth
  • SessionMgmt
  • MFA

在这里插入图片描述

第1章:入门Django与设置

1.1 Django安装与环境配置

在开始使用Django之前,需要确保已经安装了Python环境。在安装好Python后,可以使用以下命令安装Django:

pip install Django

确保已安装Django后,可以使用以下命令检查版本:

django-admin --version

1.2 创建第一个Django项目和应用

创建一个新的Django项目:

django-admin startproject myproject

进入项目目录:

cd myproject

创建一个新的Django应用:

python manage.py startapp myapp

1.3 设置基础用户模型

Django默认提供一个基本的用户模型,如果需要定制用户模型,可以在myproject/settings.py中进行设置。

例如,可以添加一个新的字段age

# myproject/settings.pyAUTH_USER_MODEL = 'myapp.NewUser'# myapp/models.pyfrom django.contrib.auth.models import AbstractUser
from django.db import modelsclass NewUser(AbstractUser):age = models.PositiveIntegerField(null=True, blank=True)def __str__(self):return f'{self.username} ({self.email})'

在数据库迁移中应用新的用户模型:

python manage.py makemigrations
python manage.py migrate

现在,已经完成了基本的Django项目和应用的创建,并设置了一个基础的用户模型。

第2章:Django认证系统

2.1 用户模型详解

在Django中,AUTH_USER_MODEL设置决定了你如何处理用户。默认的用户模型是django.contrib.auth.models.User
,但如你之前设置的,可以创建自定义用户模型。例如,NewUser模型需要继承AbstractUser,并包含username,email, 和age等字段。

2.2 用户注册、登录与验证

  • 注册:Django的UserCreationFormUserChangeForm可以用于用户注册,通常在myapp/forms.py中定义。在views.py
    中使用UserCreationForm.as_view()创建视图。
from django.contrib.auth import get_user_model
from django.urls import reverse_lazy
from django.views import genericclass RegisterView(generic.CreateView):form_class = get_user_model().forms.UserCreationFormsuccess_url = reverse_lazy('login')template_name = 'registration/register.html'
  • 登录LoginViewLogoutViewdjango.contrib.auth.views中,使用LoginView.as_view()LogoutView.as_view()
from django.contrib.auth.views import LoginView, LogoutViewclass CustomLoginView(LoginView):template_name = 'registration/login.html'
  • 验证:用户登录后,Django会自动验证用户。在views.py中,你可以使用@login_required装饰器确保只有登录用户才能访问某些视图。
from django.contrib.auth.decorators import login_required@login_required
def protected_view(request):# 只有已登录用户可以访问的视图...

2.3 自定义认证视图和URL

要自定义登录或注册视图,可以创建一个类视图并定义getpost方法。在urls.py中,使用path来映射URL到这些视图。

from django.urls import pathfrom .views import CustomLoginView, CustomRegisterViewurlpatterns = [path('login/', CustomLoginView.as_view(), name='login'),path('register/', CustomRegisterView.as_view(), name='register'),
]

2.4 CSRF保护

Django的CSRF(跨站请求伪造)保护是通过在表单中添加一个隐藏的CSRF
token来实现的。确保在所有需要用户交互的表单(如注册和登录表单)中使用{% csrf_token %}模板标签。

此外,你可以在settings.py中启用CSRF保护:

CSRF_COOKIE_NAME = 'my_custom_cookie_name'
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True

这将确保CSRF令牌的安全传输。

第3章:认证中间件和信号

3.1 中间件在认证中的作用

认证中间件

AD:首页 | 一个覆盖广泛主题工具的高效在线平台
是Django提供的一种处理请求和响应的机制,它位于视图函数之前和之后。在认证中,django.contrib.auth.middleware.AuthenticationMiddleware
负责检测请求是否已通过身份验证。如果用户未登录,中间件会重定向到登录页面。一旦用户登录,中间件会设置request.user
,使得视图可以访问用户信息。

3.2 用户登录状态管理

Django的认证系统会在用户登录后自动设置request.user,这使得在视图中可以通过request.user
访问用户信息。但如果你想在会话之外存储用户状态(例如,记住用户名),可以使用
AD:专业搜索引擎
django.contrib.auth.middleware.SessionAuthenticationMiddleware
,它会将用户信息存储在会话中。如果需要自定义登录状态的持久性,可以考虑使用django.contrib.auth.backends.RemoteUserBackend
或创建自己的Backend实现。

3.3 认证信号与事件处理

认证信号是Django的一种通知机制,用于在认证过程中触发特定事件。例如,user_logged_inuser_logged_out
信号分别在用户登录和登出时发送。你可以通过注册接收器来处理这些信号,执行额外的操作,如发送邮件通知或更新用户会话记录。

from django.contrib.auth import get_user_model
from django.dispatch import receiver
from django.db.models.signals import post_save# 注册接收器
@receiver(post_save, sender=get_user_model())
def create_or_update_user_profile(sender, instance, created, **kwargs):if created:# 用户创建时,创建用户profileelse:
# 用户更新时,更新userprofile

通过这种方式,你可以扩展Django认证系统的功能,而无需直接修改核心代码。

第4章:权限系统基础

4.1 Django内置权限模型

Django的权限系统主要依赖于django.contrib.auth.models模块中的以下几个模型:

  • User:表示用户,每个用户都有一个唯一的用户名和密码。
  • Group:用于组织用户,一个用户可以属于多个组。
  • Permission:表示一个操作或资源的权限,例如“管理博客”或“查看文章”。
  • UserPermission(也称为user_has_perm):关联用户和权限,表示用户拥有特定的权限。

4.2 用户角色与权限关联

在Django中,用户和权限通常是通过Group
来关联的。用户可以被添加到一个或多个组中,而组则被赋予了特定的权限。这样,如果一个用户属于某个具有特定权限的组,那么该用户就自动获得了该组的所有权限。通过这种方式,可以实现角色(如管理员、编辑员等)的权限管理。

4.3 分组与权限管理

  • 创建和管理组:使用Group模型,你可以创建新的组,然后将用户添加到组中。例如:
group = Group.objects.create(name='Administrators')
user = User.objects.get(username='john')
group.user_set.add(user)
  • 为组分配权限:使用Permission模型,为组赋予特定的权限,然后将组与这些权限关联起来。例如:
permission = Permission.objects.get(codename='add_article')
group.permissions.add(permission)
  • 检查用户权限:在视图中,可以使用user.has_perm()user.has_module_perms()方法检查用户是否具有特定的权限。
if request.user.has_perm('blog.add_article'):
# 用户有添加文章的权限

通过这种方式,Django的权限系统允许你以灵活的方式管理用户对应用的不同部分的访问。

第5章:自定义权限和验证

5.1 使用@permission_required装饰器

Django提供了一个名为@permission_required的装饰器,用于在视图函数中检查用户是否具有特定权限。例如:

from django.contrib.auth.decorators import permission_requireddef some_view(request):@permission_required('blog.add_article')def inner_view(request):# 视图代码,如果用户没有添加文章的权限,将被重定向到登录页面...return inner_view(request)

如果用户没有blog.add_article权限,请求会重定向到登录页面,或者根据设置显示一个403 Forbidden错误。

5.2 编写自定义权限类

Django允许你自定义权限类来实现更复杂的权限检查。创建一个继承自BasePermission的类,然后在has_permission方法中定义你的逻辑:

from django.contrib.auth.models import Permission
from django.contrib.auth.base_permissions import BasePermissionclass IsSuperAdmin(BasePermission):def has_permission(self, request, view):# 检查用户是否是超级管理员return request.user.is_superuser

然后在视图中使用这个自定义权限:

def some_view(request):permission_classes = (IsSuperAdmin,)# 使用自定义权限检查if not request.user.has_perm(IsSuperAdmin()):return HttpResponseForbidden('You are not authorized.')...

5.3 权限验证最佳实践

  • 避免硬编码:不要在代码中硬编码用户的权限检查,而应使用Django的权限系统。
  • 使用装饰器@permission_required装饰器是快速添加权限检查的好工具,但也要注意不要过度使用,可能导致代码难以理解和维护。
  • 权限分离:将权限管理与业务逻辑分离,确保权限检查独立于具体的视图。
  • 使用权限类:自定义权限类可以提供更灵活的权限控制,例如基于角色、用户组或用户属性的权限。
  • 错误处理:对于权限检查失败的情况,提供清晰的错误信息和适当的用户反馈,如重定向到登录页面或显示一个友好的错误消息。

AD:漫画首页
遵循这些最佳实践,可以确保你的权限系统既安全又易于管理。

第6章:权限管理框架(如django-guardian)

6.1 django-guardian的介绍

django-guardian是一个Django应用,用于在Django项目中实现更细粒度的权限控制。django-guardian允许你将权限授予单个对象,而不仅仅是对整个模型的访问权限。

6.2 细化权限控制

django-guardian为你提供了一种在Django中实现更细粒度的权限控制的方法。django-guardian的核心是ObjectPermission
模型,用于将权限与单个对象关联。

django-guardian允许你:

  • 为单个对象设置和管理权限。
  • 对对象进行精细的权限控制。
  • 在视图中进行简单的权限检查。

6.3 实例演示

首先,安装django-guardian:

pip install django-guardian

在你的Django项目中,添加'guardian'INSTALLED_APPS中,并在MIDDLEWARE
中添加'guardian.middleware.UpdatePermissionsMiddleware'

接下来,让我们创建一个简单的应用,并在其中使用django-guardian:

  1. 创建一个名为articles的应用:

    python manage.py startapp articles
    
  2. articles应用中,创建一个名为models.py的文件,并添加以下代码:

    from django.db import models
    from django.contrib.auth.models import User
    from guardian.shortcuts import assign_perm, get_objects_for_userclass Article(models.Model):title = models.CharField(max_length=100)content = models.TextField()author = models.ForeignKey(User, on_delete=models.CASCADE)def __str__(self):return self.title
    
  3. articles应用中,创建一个名为views.py的文件,并添加以下代码:

    from django.shortcuts import render, get_object_or_404
    from django.contrib.auth.decorators import login_required
    from django.http import HttpResponseForbidden
    from articles.models import Article, assign_perm, get_objects_for_user@login_required
    def article_list(request):user = request.userarticles = get_objects_for_user(user, 'articles.view_article', klass=Article)return render(request, 'articles/article_list.html', {'articles': articles})@login_required
    def assign_article_permissions(request, article_id):user = request.userarticle = get_object_or_404(Article, id=article_id)if request.method == 'POST':if user.has_perm('articles.change_article', article):assign_perm('articles.view_article', user, article)return HttpResponse('Assigned view permission.')else:return HttpResponseForbidden('You do not have the permission to change article.')return render(request, 'articles/assign_permissions.html', {'article': article})
    
  4. articles应用中,创建一个名为templates/articles的文件夹,并在其中创建一个名为assign_permissions.html的文件:

    <form method="post">{% csrf_token %}<input type="submit" value="Assign Permission">
    </form>
    
  5. articles应用中,创建一个名为urls.py的文件,并添加以下代码:

    from django.urls import path
    from . import viewsurlpatterns = [path('', views.article_list, name='article_list'),path('assign_permissions/<int:article_id>/', views.assign_article_permissions, name='assign_permissions'),
    ]
    
  6. 在你的项目中,将articles应用的urls.py添加到主urls.py中:

    from django.contrib import admin
    from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('articles/', include('articles.urls')),
    ]
    

现在,你可以运行你的项目,并在文章列表中查看权限管理的实例。在这个例子中,我们使用django-guardian为每个用户分配了对文章的特定视图权限。

你可以使用django-guardian的assign_permget_objects_for_user
函数来分配和检查权限。在这个例子中,我们使用了一个名为view_article的权限,可以在admin.py中进行定义:

from django.contrib import admin
from django.contrib.auth.models import Permission
from articles.models import Articleclass ArticleAdmin(admin.ModelAdmin):list_display = ('title', 'author')def save_model(self, request, obj, form, change):if not obj.pk:assign_perm('articles.view_article', request.user, obj)obj.save()admin.site.register(Article, ArticleAdmin)

这样,当你在Django管理界面中创建一个新文章时,将自动为当前用户分配view_article权限。

django-guardian为你提供了一种更细粒度的权限控制方法,可以在Django项目中实现更强大的权限管理。

第7章:视图和模板的权限控制

7.1 在视图中检查权限

在Django中,视图是处理HTTP请求的函数或类。为了在视图中检查用户的权限,可以使用django-guardian提供的has_perm
get_objects_for_user函数。以下是一个基本的视图检查权限的例子:

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from guardian.shortcuts import has_perm@login_required
def some_view(request):user = request.userarticle = Article.objects.get(pk=1)  # 假设你有一个名为Article的模型# 检查用户是否有查看文章的权限if not has_perm('articles.view_article', article, user):return HttpResponseForbidden("You don't have permission to view this article.")# 如果用户有权限,继续执行# ...return render(request, 'some_template.html', {'article': article})

在这个例子中,has_perm函数检查用户是否有指定的权限(在这个例子中是articles.view_article)对给定的对象(article)。

7.2 在模板中显示权限相关信息

在模板中,你可能想要显示用户是否具有特定的权限。Django模板语言允许你使用条件语句来检查这些权限。以下是一个简单的例子:

{% if user.has_perm('articles.view_article', article) %}
<p>You have permission to view this article.</p>
{% else %}
<p>You do not have permission to view this article.</p>
{% endif %}

在这个模板片段中,如果用户具有articles.view_article权限,has_perm表达式会返回True,否则返回False,从而决定显示不同的内容。

你也可以在模板中使用get_objects_for_user来获取用户具有特定权限的对象,并根据这些对象的内容进行渲染:

{% if object_list %}
<ul>{% for object in object_list %}{% if user.has_perm('articles.view', object) %}<li>{{ object.title }} (You can view)</li>{% else %}<li>{{ object.title }} (You cannot view)</li>{% endif %}{% endfor %}
</ul>
{% else %}
<p>No objects found.</p>
{% endif %}

这样,模板会根据用户的权限动态地显示内容,提供一个用户友好的界面。

第8章:RESTful API的认证与权限

8.1 Django REST framework的认证集成

Django REST
framework提供了多种认证方式,包括基本认证(BasicAuthentication)、令牌认证(TokenAuthentication)和会话认证(SessionAuthentication)等。可以在项目的设置文件中进行配置。以下是一个基本的认证配置示例:

# settings.pyREST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework.authentication.BasicAuthentication','rest_framework.authentication.SessionAuthentication',)
}

在这个配置中,REST framework将使用基本认证和会话认证来处理API请求。

8.2 API权限控制策略

API权限控制是确保API的安全性和保护数据的重要部分。Django REST
framework提供了多种权限控制策略,包括只读权限(ReadOnly)、对象级权限(ObjectPermissions)和自定义权限类(CustomPermission)等。可以在视图中配置权限控制策略。以下是一个使用对象级权限的视图示例:

from rest_framework import viewsets, permissionsfrom myapp.models import Article
from myapp.serializers import ArticleSerializerclass ArticleViewSet(viewsets.ModelViewSet):queryset = Article.objects.all()serializer_class = ArticleSerializerpermission_classes = [permissions.DjangoModelPermissions]

在这个视图中,我们使用了DjangoModelPermissions,这意味着用户只能访问他们拥有的对象。如果用户试图访问他们不拥有的对象,REST
framework将返回一个403 Forbidden响应。

如果你需要更细粒度的权限控制,可以使用自定义权限类。以下是一个简单的自定义权限类示例:

from rest_framework import permissionsclass CustomPermission(permissions.BasePermission):def has_object_permission(self, request, view, obj):if request.user.is_staff:return Truereturn Falseclass ArticleViewSet(viewsets.ModelViewSet):queryset = Article.objects.all()serializer_class = ArticleSerializerpermission_classes = [CustomPermission]

在这个示例中,我们创建了一个名为CustomPermission的自定义权限类,它只允许管理员用户访问API。如果用户不是管理员,则返回一个403
Forbidden响应。

总之,Django REST framework为RESTful API的认证和权限控制提供了多种方式和工具,可以根据项目需求进行选择和定制。

第9章:高级主题

9.1 用户会话管理

在Web应用程序中,用户会话管理是非常重要的,它涉及到用户登录、注销和会话状态的管理。Django提供了内置的会话管理功能,而Django
REST framework也提供了相应的支持。通过使用SessionAuthentication认证类,Django REST framework可以与Django的会话管理系统集成,从而实现用户会话管理。

# settings.pyREST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework.authentication.SessionAuthentication',)
}

通过将SessionAuthentication添加到DEFAULT_AUTHENTICATION_CLASSES中,可以启用基于会话的认证,从而实现用户会话管理。

9.2 客户端认证(OAuth2、JWT等)

客户端认证是指在API请求中对客户端进行身份验证的过程。Django REST framework支持多种客户端认证方式,包括OAuth2和JWT(JSON Web
Token)等。这些认证方式可以通过第三方库来实现,比如djangorestframework-simplejwt用于JWT认证。

以下是一个简单的JWT认证配置示例:

# settings.pyREST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',)
}

通过将JWTAuthentication添加到DEFAULT_AUTHENTICATION_CLASSES中,可以启用JWT认证,从而实现客户端认证。

9.3 多因素认证(MFA)

多因素认证是指在用户登录或进行敏感操作时,除了用户名和密码外,还需要提供第二种或多种身份验证因素的过程。Django REST
framework本身并没有内置的多因素认证功能,但可以通过结合第三方库来实现。例如,可以使用django-mfa等库来实现多因素认证功能。

通过使用这些第三方库,可以实现诸如短信验证码、一次性密码(OTP)等多因素认证方式,从而提高系统的安全性。

综上所述,Django REST framework提供了丰富的支持,可以轻松实现用户会话管理、客户端认证和多因素认证等高级主题。开发人员可以根据项目需求选择合适的认证方式,并结合相关的第三方库来实现所需的功能。

第10章:实战项目

建立一个简单的博客系统是一个很好的实战项目,可以涵盖认证与权限控制等方面。下面是一个基本的Django REST
framework博客系统的示例,其中包括了认证与权限控制的应用。

首先,我们需要创建一个Django应用,并定义博客文章的模型、序列化器、视图和URL配置。

# models.py
from django.db import modelsclass Post(models.Model):title = models.CharField(max_length=100)content = models.TextField()author = models.ForeignKey('auth.User', on_delete=models.CASCADE)created_at = models.DateTimeField(auto_now_add=True)# serializers.py
from rest_framework import serializers
from .models import Postclass PostSerializer(serializers.ModelSerializer):class Meta:model = Postfields = ['id', 'title', 'content', 'author', 'created_at']# views.py
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializerclass PostViewSet(viewsets.ModelViewSet):queryset = Post.objects.all()serializer_class = PostSerializer# urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import PostViewSetrouter = DefaultRouter()
router.register(r'posts', PostViewSet)urlpatterns = [path('', include(router.urls)),
]

接下来,我们将添加认证与权限控制。

# settings.pyINSTALLED_APPS = [# ...'rest_framework','blog',  # assuming 'blog' is the name of the app
]REST_FRAMEWORK = {'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated',],'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.SessionAuthentication','rest_framework.authentication.TokenAuthentication',],
}

在上述代码中,我们将默认权限设置为IsAuthenticated,这意味着只有经过身份验证的用户才能访问API。我们还配置了SessionAuthentication和TokenAuthentication作为默认的认证类,这样用户可以使用会话验证或令牌验证进行身份验证。

最后,我们需要为用户创建博客文章的权限。我们可以使用Django的自定义权限类来实现这一点。

# permissions.py
from rest_framework import permissionsclass IsAuthorOrReadOnly(permissions.BasePermission):def has_object_permission(self, request, view, obj):if request.method in permissions.SAFE_METHODS:return Truereturn obj.author == request.user

然后,将这个权限类应用到我们的视图中。

# views.py
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
from .permissions import IsAuthorOrReadOnlyclass PostViewSet(viewsets.ModelViewSet):queryset = Post.objects.all()serializer_class = PostSerializerpermission_classes = [IsAuthorOrReadOnly]

现在,我们已经完成了一个简单的博客系统,并应用了认证与权限控制。用户需要经过身份验证才能访问API,并且只有文章的作者才有权限对文章进行修改或删除。

第11章:最佳实践与高级技巧

性能优化

  1. 数据库优化:使用索引、合理设计数据库结构、避免N+1查询等。
  2. 缓存:使用缓存技术(如Redis、Memcached)缓存频繁访问的数据。
  3. 异步任务:将耗时任务异步化,可以使用Celery等工具。
  4. 代码优化:避免过多的数据库查询、减少不必要的计算、优化算法等。

安全注意事项

  1. 数据加密:对敏感数据进行加密存储。
  2. 防止跨站脚本攻击(XSS) :对用户输入进行过滤和转义。
  3. 防止SQL注入:使用ORM或参数化查询来防止SQL注入攻击。
  4. 权限控制:确保用户只能访问其有权限的资源。
  5. 保持系统更新:定期更新框架、库和操作系统,以修复潜在的安全漏洞。

未来趋势与更新

  1. 微服务架构:将应用拆分为小型的、独立部署的服务。
  2. 容器化:使用Docker等容器技术实现应用的快速部署和扩展。
  3. Serverless架构:无需管理服务器,按需运行代码,降低运维成本。
  4. 人工智能与机器学习:将人工智能技术应用于应用开发中,实现智能化功能。
  5. 持续集成与持续部署:采用CI/CD流程实现快速迭代和交付。

附录

Django官方文档链接

你可以在Django官方文档中找到最新的Django文档,包括教程、API参考和发布说明等。

常见问题解答

  1. Stack Overflow:在Stack Overflow上搜索相关问题,通常能找到解决方案。
  2. Django官方论坛:官方网站上有一个社区论坛,你可以在这里提问和寻求帮助。
  3. GitHub Issues:如果你使用的是开源的Django项目或库,可以在对应的GitHub仓库的Issues中查找或提问问题。

工具和库推荐

  1. Django REST framework:用于构建Web API的强大工具。
  2. Celery:用于处理异步任务和定时任务的分布式任务队列。
  3. Django Debug Toolbar:用于在开发阶段进行性能分析和调试的工具。
  4. Django Channels:为Django引入了实时的、异步的通信协议,用于构建实时应用。
  5. Django Allauth:提供了完整的用户认证和账户管理功能,包括社交账号登录、邮箱验证等。

这些工具和库都是Django社区广泛使用和推荐的,可以帮助你更高效地开发和管理Django应用。

相关文章:

深入Django:用户认证与权限控制实战指南

title: 深入Django&#xff1a;用户认证与权限控制实战指南 date: 2024/5/7 18:50:33 updated: 2024/5/7 18:50:33 categories: 后端开发 tags: AuthDecoratorsPermissionsGuardianRESTAuthSessionMgmtMFA 第1章&#xff1a;入门Django与设置 1.1 Django安装与环境配置 在…...

Kubernetes - Dashboard 配置用户名密码方式登录

Kubernetes - Dashboard 配置用户名密码方式登录 前言&#xff1a; 为了 K8s 集群安全&#xff0c;默认情况下 Dashboard 以 Token的形式登录的&#xff0c;那如果我们想以用户名/密码的方式登录该怎么操作呢&#xff1f;其实只需要我们创建用户并进行 ClusterRoleBinding绑定即…...

AIGC能给人类社会带来哪些变革?

随着人工智能技术的飞速发展&#xff0c;AIGC&#xff08;人工智能生成内容&#xff09;正在成为推动社会变革的重要力量。本文将从技术角度出发&#xff0c;探讨AIGC技术如何影响和改变人类生活的各个方面。 一、AIGC技术概述 AIGC&#xff0c;即人工智能生成内容&#xff0…...

医药垃圾分类管理系统|基于SSM医药垃圾分类管理系统的系统设计与实现(源码+数据库+文档)

医药垃圾分类管理系统 目录 基于SSM医药垃圾分类管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统登录模块 2管理员模块实现 3用户模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博…...

用vim或gvim编辑程序

vim其实不难使用&#xff0c;学习一下就好了。简单功能很快学会。它有三种模式&#xff1a;命令模式&#xff0c;编辑模式&#xff0c;视模式。打开时在命令模式。在命令模式下按 i 进入编辑模式&#xff0c;在编辑模式下按<Esc>键退出编辑模式。在命令模式按 :wq 保存文…...

linus下Anaconda创建虚拟环境pytorch

一、虚拟环境 1.创建 输入下面命令 conda create -n env_name python3.8 输入y 2.激活环境 输入 conda activate env_name 二、一些常用的命令 在Linux的控制平台 切换到当前的文件夹 cd /根目录/次目录 查看conda目录 conda list 查看pip目录 pip list查看历史命…...

synchronized与volatile关键字

1.synchronized的特性 1.1互斥 synchronized 会起到互斥效果, 某个线程执行到某个对象的 synchronized 中时, 其他线程如果也执行到 同一个对象 synchronized 就会阻塞等待. 进入 synchronized 修饰的代码块, 相当于 加锁 退出 synchronized 修饰的代码块, 相当于 解锁 syn…...

Python基础之运算符操作

在Python中&#xff0c;运算符的作用就是用于执行各种的运算操作&#xff0c;常见的运算符有算数运算符、比较运算符、逻辑运算符、赋值运算符、成员运算符、身份运算符等。下面我们就来看看在Python中这些运算的详细操作。 算术运算符 算术运算符是用来执行一些基本的数学运…...

【busybox记录】【shell指令】uniq

目录 内容来源&#xff1a; 【GUN】【uniq】指令介绍 【busybox】【uniq】指令介绍 【linux】【uniq】指令介绍 使用示例&#xff1a; 去除重复行 - 默认输出 去除重复行 - 跳过第n段&#xff08;空格隔开&#xff09;&#xff0c;比较n1以后的内容&#xff0c;去重 去…...

Nginx从入门到精通速成

文章目录 一. **Nginx** **的简介**1.1 什么是 **nginx**1.2 正向代理1.3 反向代理1.4 **负载均衡**1.5 动静分离 二. **Nginx** **的安装**三. **Nginx** **的常用的命令**四. **Nginx** **的配置文件**五. **Nginx** **配置实例**反向代理实例**1**5.1 实现效果5.2 准备工作5…...

Flutter笔记:Widgets Easier组件库(4)使用按钮组

Flutter笔记 Widgets Easier组件库&#xff08;4&#xff09;&#xff1a;使用按钮组 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress…...

Docker常用命令 镜像库设置

Docker常用命令 & 镜像库设置 1. 镜像操作2. 容器操作3. 网络操作4. Docker Compose操作5. Docker volume操作6. Docker run介绍7. 镜像库设置 1. 镜像操作 列出本地所有的镜像 docker images从远程仓库拉取镜像到本地 docker pull <image_name>删除本地的指定镜像…...

无人零售,重塑购物新纪元

在这个快节奏的时代&#xff0c;科技的每一次跃进都在悄无声息地改变着我们的生活方式。而今&#xff0c;无人零售正以雷霆之势&#xff0c;颠覆传统购物模式&#xff0c;为我们带来前所未有的便捷与智能体验。想知道无人零售如何彻底改变我们的购物方式吗&#xff1f;跟随我&a…...

【图片格式转换】ICO、JPG、JPEG、PNG图片格式在线免费转换

ICO、JPG、JPEG、PNG图片格式转换 图片格式转换 https://orcc.online 支持ICO、JPG、JPEG、PNG等 主页 https://www.orcc.online 其他工具 pdf在线免费转word文档 https://orcc.online/pdf 时间戳转换 https://orcc.online/timestamp Base64 编码解码 https://orcc.onlin…...

通过自然语言处理执行特定任务的AI Agents;大模型控制NPC执行一系列的动作;个人化的电子邮件助手Panza

✨ 1: OpenAgents 通过自然语言处理执行特定任务的AI代理 OpenAgents是一个开放平台&#xff0c;旨在使语言代理&#xff08;即通过自然语言处理执行特定任务的AI代理&#xff09;的使用和托管变得更加便捷和实用。它特别适合于日常生活中对数据分析、工具插件获取和网络浏览…...

4.2 JavaScript语法

4.2.1 JavaScript大小写 在JavaScript中大小写是严格区分的&#xff0c;无论是变量、函数名称、运算符和其他语法都必须严格按照要求的大小写进行声明和使用。例如变量hello与变量HELLO会被认为是完全不同的内容。 4.2.2 JavaScript分号 很多编程语言&#xff08;例如C、Java和…...

面试二十五、remove和earse的区别

vector中erase的作用是删除掉某个位置position或一段区域&#xff08;begin, end)中的元素&#xff0c;减少其size&#xff0c;返回被删除元素下一个元素的位置。 vector中remove的作用是将范围内为val的值都remove到后面&#xff0c;返回新的_last值&#xff08;非val部分的en…...

普乐蛙元宇宙VR体验馆设备集体亮相VR文旅景区展

普乐蛙全国巡展又双叒叕开始了! 这次来到的是“好客山东”↓↓ 山东2024休闲旅游产业展 4月25日至27日&#xff0c;2024休闲旅游产业展在临沂国际博览中心举办。本次展会以“潮购文旅好品&#xff0c;乐享时尚生活”为主题&#xff0c;汇聚全国文旅产业上下游500多家企业、上万…...

北京大学-知存科技存算一体联合实验室揭牌,开启知存科技产学研融合战略新升级

5月5日&#xff0c;“北京大学-知存科技存算一体技术联合实验室”在北京大学微纳电子大厦正式揭牌&#xff0c;北京大学集成电路学院院长蔡一茂、北京大学集成电路学院副院长鲁文高及学院相关负责人、知存科技创始人兼CEO王绍迪、知存科技首席科学家郭昕婕博士及企业研发相关负…...

项目总结(一)docker总结

目录 一、引言 二、docker ------>2.1、docker介绍 ------>2.2、与虚拟机的区别 ------>2.3、Docke基本概念 ------>2.4、Docker内部结构 ------>2.5、Windows上使用docker ------>2.6、Linux上使用Docker ------>2.7、Docker常用命令 ------&g…...

深圳比创达EMC|EMC一站式解决方案:助力电子产品电磁兼容性升级

在当今电子信息技术飞速发展的时代&#xff0c;电磁兼容性&#xff08;EMC&#xff09;问题日益凸显&#xff0c;成为制约电子产品性能和质量的关键因素。为了满足市场对EMC问题的迫切需求&#xff0c;EMC一站式解决方案应运而生&#xff0c;成为解决EMC问题的有效途径。 一、…...

万兆以太网MAC设计(11)完整UDP协议栈仿真

文章目录 前言一、模块接口二、IP模块与ARP模块之间的联系三、整体协议栈仿真总结&#xff1a; 前言 目前除了巨帧处理逻辑之外&#xff0c;所有的准备工作都已经结束了&#xff0c;先进行整体的功能验证。 一、模块接口 所有模块接口皆采用AXIS数据流的形式&#xff0c;其中…...

【牛客】【模板】差分

原题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 差分模板。 b[0]a[0]; b[1]a[1]-a[0]; b[2]a[2]-a[1]; ...... b[n-1]a[n-1]-a[n-2]; b[n]a[n]-a[n-1]; 差分标记&#xff1a;b[l]k,b…...

鸿蒙内核源码分析(中断管理篇) | 江湖从此不再怕中断

关于中断部分系列篇将用三篇详细说明整个过程. 中断概念篇 中断概念很多&#xff0c;比如中断控制器&#xff0c;中断源&#xff0c;中断向量&#xff0c;中断共享&#xff0c;中断处理程序等等.本篇做一次整理.先了解透概念才好理解中断过程.用海公公打比方说明白中断各个概念…...

php使用rabbitmq

这里使用的是 php-amqplib composer require php-amqplib/php-amqplib生产端send.php <?phprequire_once "./vendor/autoload.php";use PhpAmqpLib\Connection\AMQPStreamConnection; use PhpAmqpLib\Message\AMQPMessage;//交换机名称 $exc_name exchange.can…...

前端发起网络请求的几种常见方式(XMLHttpRequest、FetchApi、jQueryAjax、Axios)

摘要 前端发起网络请求的几种常见方式包括&#xff1a; XMLHttpRequest (XHR)&#xff1a; 这是最传统和最常见的方式之一。它允许客户端与服务器进行异步通信。XHR API 提供了一个在后台发送 HTTP 请求和接收响应的机制&#xff0c;使得页面能够在不刷新的情况下更新部分内容…...

通过氧气退火增强β-Ga₂O₃二极管.中国科技大学和河北半导体研究所的研究人员在这一特定领域取得了最新重大进展

上图所示&#xff1a;&#xff08;a&#xff09;增加台面有助于提高β-Ga2O3肖特基势垒二极管的阻断电压&#xff08;b&#xff09;。 氧气退火和自对准台面终端使β-Ga2O3二极管进一步走向商业化。 虽然β-Ga2O3电力电子技术已经取得了长足的进步&#xff0c;但仍然存在挑战&…...

C语言猜数字游戏

用C语言实现猜数字游戏&#xff0c;电脑随机给出一个范围内的数字&#xff0c;用户在终端输入数字&#xff0c;去猜大小&#xff1b;对比数字&#xff0c;电脑给出提示偏大还是偏小&#xff1b;不断循环&#xff0c;直到正确 #include <stdio.h> #include <time.h>…...

笔记本连接不上远程桌面,笔记本无法连接远程桌面的可能原因及解决方法

在使用远程桌面功能时&#xff0c;笔记本无法成功连接的情况可能由多种原因引起。为了有效地解决这个问题&#xff0c;我们需要逐一排查这些可能的原因&#xff0c;并采取相应的解决措施。 首先&#xff0c;网络连接稳定性是远程桌面连接成功的关键。请确保笔记本和远程计算机之…...

Android 音视频播放器 Demo(一)—— 视频解码与渲染

本篇作为 Android 音视频实战系列的第二篇文章&#xff0c;主要介绍视频解码与渲染过程。本系列文章目录如下&#xff1a; Android 音视频基础知识 Android 音视频播放器 Demo&#xff08;一&#xff09;—— 视频解码与渲染 Android 音视频播放器 Demo&#xff08;二&#xff…...

Flutter笔记:Widgets Easier组件库(3)使用按钮组件

Flutter笔记 Widgets Easier组件库&#xff08;3&#xff09;&#xff1a;使用按钮组件 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddre…...

荷香堪筑梦,鸳鸯和月寻。(变相BFS搜索)

本题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 题目&#xff1a; 样例&#xff1a; 输入 3 4 2 .... ***. ..a. 输出 yes 思路&#xff1a; 根据题意&#xff0c;这里 1 s 可以移动多次&#xff0c;我们将每次可以移动避开雪的的位置存储起来&#xff0c;判断当…...

智慧公厕建设,打造智慧城市基础设施新亮点

公共厕所是城市基础设施的重要组成部分&#xff0c;而智慧公厕的建设则是现代城市管理的创新之举。为了实现公厕的精细化管理和提供更便捷的服务&#xff0c;推进智慧公厕建设必须要实现技术融合、业务融合、数据融合的目标&#xff0c;跨越层级、地域、系统、部门和业务的限制…...

Kubernetes 教程:在 Containerd 容器中使用 GPU

原文链接:Kubernetes 教程:在 Containerd 容器中使用 GPU 云原生实验室本文介绍了如何在使用 Containerd 作为运行时的 Kubernetes 集群中使用 GPU 资源。https://fuckcloudnative.io/posts/add-nvidia-gpu-support-to-k8s-with-containerd/ 前两天闹得沸沸扬扬的事件不知道…...

LNMP部署wordpress

1.环境准备 总体架构介绍 序号类型名称外网地址内网地址软件02负载均衡服务器lb0110.0.0.5192.168.88.5nginx keepalived03负载均衡服务器lb0210.0.0.6192.168.88.6nginx keepalived04web服务器web0110.0.0.7192.168.88.7nginx05web服务器web0210.0.0.8192.168.88.8nginx06we…...

本地部署大模型ollama+docker+open WebUI/Lobe Chat

文章目录 大模型工具Ollama下载安装运行Spring Ai 代码测试加依赖配置写代码 ollama的web&Desktop搭建部署Open WebUI有两种方式Docker DesktopDocker部署Open WebUIDocker部署Lobe Chat可以配置OpenAI的key也可以配置ollama 大模型的选择 本篇基于windows环境下配置 大模型…...

qt学习篇---界面按键关联(信号和槽)

目录 1.qt基础 2.做一个界面 创建project UI界面设计 信号和槽 1.控件改名字 2.什么是信号和槽 3.怎么关联信号和槽 自动关联 手动关联 1.qt基础 qt可移植性强&#xff0c;不久会用到MCU。很有意义学习 2.做一个界面 创建project 不要中文路径 选择QWidget .pro文件…...

python Django 的内置权限系统或自定义模型来存储更复杂的角色和权限关系

在 Django 中,管理用户权限和角色通常涉及到使用 Django 的内置权限系统或自定义模型来存储更复杂的角色和权限关系。下面是一个基本的指南,说明如何在 Django 中为后台管理系统分配权限并将其保存在数据库中,同时结合 Vue.js 和 Element UI 作为前端框架。 后端(Django)…...

不上班,我靠这5份赚钱副业养活了自己

在这个快节奏的社会里&#xff0c;很多人都在为生活奔波忙碌。今天&#xff0c;就让我来跟大家分享一下我的“躺平”秘籍吧&#xff01; 这一个月来&#xff0c;我没有上班&#xff0c;但好在有副业养活自己。有时候&#xff0c;我真的觉得有一份自己喜欢的自媒体副业挺好的。…...

强一致性的皇冠:分布式事务模型的至高法则揭秘

关注微信公众号 “程序员小胖” 每日技术干货&#xff0c;第一时间送达&#xff01; 引言 分布式事务模型是分布式系统设计的核心&#xff0c;关键在于保证数据一致性和事务完整性&#xff0c;尤其强调强一致性。诸如2PC、3PC、Saga、TCC等模型与协议&#xff0c;应运而生以解…...

mac/windows下安装docker,minikube

1、安装docker Get Started | Docker 下载安装docker 就行 启动后&#xff0c;就可以正常操作docker了 使用docker -v 验证是否成功就行 2、安装minikube&#xff0c;是基于docker-desktop的 2.1、点击设置 2.2、选中安装&#xff0c;这个可能需要一点时间 这样安装后&…...

【爬虫】fake_useragent的使用、BeautifulSoup(find()和find_all())

1 fake_useragent 2 BeautifulSoup 3 Beautiful Soup库的find()和find_all() 1 fake_useragent fake_useragent是一个Python库&#xff0c;用于生成随机的用户代理字符串。 用户代理是在HTTP请求中发送给服务器的一种标识&#xff0c;它告诉服务器发送请求的客户端的类型、版本…...

ComfyUI中图像亮度/对比度/饱和度处理

用上面这个节点可以同时设置图片的亮度、对比度和饱和度。 【保姆级教程】一口气分享在ComfyUI中常用的30多种基本图像处理方式 更多好玩且实用AIGC工作流和节点 星球号&#xff1a;32767063 本期资料链接 往期学习资料 整理AI学习资料库...

基于FPGA的DDS波形发生器VHDL代码Quartus仿真

名称&#xff1a;基于FPGA的DDS波形发生器VHDL代码Quartus仿真&#xff08;文末获取&#xff09; 软件&#xff1a;Quartus 语言&#xff1a;VHDL 代码功能&#xff1a; DDS波形发生器VHDL 1、可以输出正弦波、方波、三角波 2、可以控制输出波形的频率 DDS波形发生器原理…...

C++语法|可调用对象与function类型

文章目录 引入function的使用function类型的典型应用function类型的原理实现代码优化可变参的函数对象 引入 还记得C语言中的函数指针数组吗&#xff1f; 我们通过函数指针数组实现一个&#xff0c;图书管理系统的界面&#xff1a; #include <stdio.h> void doShowAllB…...

Linux学习之路 -- 文件 -- 文件描述符

前面介绍了与文件相关的各种操作&#xff0c;其中的各个接口都离不开一个整数&#xff0c;那就是文件描述符&#xff0c;本文将介绍文件描述符的一些相关知识。 目录 <1>现象 <2>原理 文件fd的分配规则和利用规则实现重定向 <1>现象 我们可以先通过prin…...

JDK动态代理和Cglib动态代理区别

1.如果目标类实现了接口&#xff0c;将会使用JDK动态代理&#xff0c;否则会使用Cglib动态代理; 2.JDK代理使用自己的字节码生成工具生成代理对象&#xff0c;而Cglib会使用ASM字节码生成工具去生成; 3.JDK动态代理是通过反射的方式去实现代理对象的所有方法&#xff0c;通过…...

牛客 | 字符金字塔

请打印输出一个字符金字塔&#xff0c;字符金字塔的特征请参考样例 #include <stdio.h> #include <string.h> using namespace std; int main() {char c;scanf("%c", &c);for (int i 1; i < (c - 64); i)//第一个循环决定了有多少行{//c:67 第三…...

【计算机科学速成课】笔记三——操作系统

文章目录 18.操作系统问题引出——批处理设备驱动程序多任务处理虚拟内存内存保护Unix 18.操作系统 问题引出—— Computers in the 1940s and early 50s ran one program at a time. 1940,1950 年代的电脑&#xff0c;每次只能运行一个程序 A programmer would write one at…...

用js代码实现贪吃蛇小游戏

js已经学了大部分了&#xff0c;现在就利用我所学的js知识试试做贪吃蛇小游戏吧 以下部分相关图片以及思路笔记均出自渡一陈老师的视频 首先制作简单的静态页面&#xff0c;添加贪吃蛇移动的背景和相关图片&#xff0c;比如开始游戏等等 将各个功能均封装在函数中&#xff0…...