6.寻光集后台管理系统-用户管理(注册视图)

django中视图本质上就是个函数,接受用户传入的请求,返回对应的响应。

在视图中处理业务逻辑。django约定将视图放在views.py的文件中。这个文件应放在项目或者应用目录中。

函数视图

基于函数的视图

def some_view(request):
  dosometing
  return HttpResponse(html)

特点:

  1. 逻辑清晰好理解

  2. 复用性较差

类视图

基于类的视图,换了一种写法,不能替代函数视图,有一些优势:

  • 用特定的方法去管理http方法(get post)

  • 使用面向对象的技术,可以将代码分解成可重用的组件

所以后续大部分会采用类视图的方式编写代码

注册视图

注册需要前端发起一个携带需要注册的账号密码的post请求

这种常规的增删改查视图DRF已经封装好了,直接进行继承即可

from rest_framework import generics

class UserRegisterView(generics.CreateAPIView):
    serializer_class = UserRegisterSerializer

只需要两行就完成了注册类视图的编写

看一下CreateAPIView类具体干了什么,可以点击进行跳转

class CreateAPIView(mixins.CreateModelMixin,
                    GenericAPIView):
    """
    Concrete view for creating a model instance.
    """
    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

它就是接收了响应,然后把响应数据传递给create函数

class CreateModelMixin:
    """
    Create a model instance.
    """
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save()

    def get_success_headers(self, data):
        try:
            return {'Location': str(data[api_settings.URL_FIELD_NAME])}
        except (TypeError, KeyError):
            return {}

分步查看一下它都干了什么

1. 获取请求数据

serializer = self.get_serializer(data=request.data)

查看其中的get_serializer

def get_serializer(self, *args, **kwargs):
    kwargs['context'] = self.get_serializer_context()
    return self.serializer_class(*args, **kwargs)

def get_serializer_context(self):
    return {
        'request': self.request,
        'format': self.format_kwarg,
        'view': self
    }

这里的serializer_class就是指定我们编写的序列化器UserRegisterSerializer

就是这一步把前端传递过来的json对象,处理成了一个python对象

2. 数据校验

serializer.is_valid(raise_exception=True)

从上一步可以看出,这里的serializer就是UserRegisterSerializer的实例化对象

UserRegisterSerializer又是继承的serializers.ModelSerializer

所以这个is_valid的路径为rest_framework.serializers.BaseSerializer.is_valid

def is_valid(self, raise_exception=False):
    assert hasattr(self, 'initial_data'), (
        'Cannot call `.is_valid()` as no `data=` keyword argument was '
        'passed when instantiating the serializer instance.'
    )

    if not hasattr(self, '_validated_data'):
        try:
            self._validated_data = self.run_validation(self.initial_data)
        except ValidationError as exc:
            self._validated_data = {}
            self._errors = exc.detail
        else:
            self._errors = {}

    if self._errors and raise_exception:
        raise ValidationError(self.errors)

    return not bool(self._errors)

暂时了解它的功能就是去判断数据是否符合我们的规定即可

3. 保存数据

self.perform_create(serializer)

def perform_create(self, serializer):
    serializer.save()

同上,save方法调用的是rest_framework.serializers.BaseSerializer.save

def save(self, **kwargs):
    assert hasattr(self, '_errors'), (
        'You must call `.is_valid()` before calling `.save()`.'
    )

    assert not self.errors, (
        'You cannot call `.save()` on a serializer with invalid data.'
    )

    # Guard against incorrect use of `serializer.save(commit=False)`
    assert 'commit' not in kwargs, (
        "'commit' is not a valid keyword argument to the 'save()' method. "
        "If you need to access data before committing to the database then "
        "inspect 'serializer.validated_data' instead. "
        "You can also pass additional keyword arguments to 'save()' if you "
        "need to set extra attributes on the saved model instance. "
        "For example: 'serializer.save(owner=request.user)'.'"
    )

    assert not hasattr(self, '_data'), (
        "You cannot call `.save()` after accessing `serializer.data`."
        "If you need to access data before committing to the database then "
        "inspect 'serializer.validated_data' instead. "
    )

    validated_data = {**self.validated_data, **kwargs}

    if self.instance is not None:
        self.instance = self.update(self.instance, validated_data)
        assert self.instance is not None, (
            '`update()` did not return an object instance.'
        )
    else:
        self.instance = self.create(validated_data)
        assert self.instance is not None, (
            '`create()` did not return an object instance.'
        )

    return self.instance

这个save方法兼容了更新新建两个操作

如果self.instance非空,则是更新。否则为新建

新建的时候调用的create方法

def create(self, validated_data):
    raise NotImplementedError('`create()` must be implemented.')

这个创建是个抽象方法,所以需要我们去实现它

我们在users.serializers.UserRegisterSerializer.create中实现了它

def create(self, validated_data):
    validated_data.pop('password_confirm')
    return User.objects.create_user(**validated_data)

至此就完成了注册

小结

虽然分析了一堆,但是实际上代码只有

from rest_framework import generics
from users.serializers import UserRegisterSerializer


class UserRegisterView(generics.CreateAPIView):
    serializer_class = UserRegisterSerializer

路由

路由的作用和路由器类似,当一个用户请求django站点的一个页面时,是路由系统通过对url的路径部分进行匹配,一旦匹配成功就导入并执行对应的视图来返回响应。

  1. 当一个请求来到时,django首先到项目中查找根路由模式,在其中查找路由匹配规则。

  2. 根路由模块,就是项目文件目录下的urls.py文件。这个文件中定义了一个变量urlpatterns。它应该是一个django.urls.path(),或者是django.urls.re_path()对象的列表。

  3. django按顺序运行每个url模式,并在与请求的url匹配的第一个模式停止。

  4. 一旦其中一个url模式匹配,django将导入并调用给定的视图。

  5. 如果没有匹配,或者在此过程中引发任何异常,django调用错误视图。

注册路由

根路由

在根路由backend/LightSeeking/urls.py中添加

path('users/', include('users.urls')),

表示前端可以使用http://IP:端口/users/xx来访问users.urls里面的路由

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('users/', include('users.urls')),
]

include可以接收一个表示导入路由模块的字符串,也可以接收一个路由模式列表。

include(module, namespace=None)
include(pattern_list)
include((pattern_list, app_namespace), namespace=None)

应用路由

在users文件夹中新建一个urls.py文件来管理应用的路由

写上注册的路由

from django.urls import path
from . import views

urlpatterns = [
    path('register/', views.UserRegisterView.as_view(), name='register'),
]

测试

至此完成了序列化器+视图+路由,那么我们就可以发起注册请求了

打开postman来进行测试

请求地址:http://127.0.0.1:8000/users/register/

请求方式:POST

请求数据:

{
  "username": "zhongxin",
  "password": "123456",
  "password_confirm": "123456",
  "email": "490336534@qq.com",
  "mobile": "13000000000",
  "name": "测试游记"
}

发送请求

ae3ad3510c37dc7f85fb2e016b90638a.jpeg

查看响应

{
    "id": 1,
    "username": "zhongxin",
    "email": "490336534@qq.com",
    "mobile": "13000000000",
    "name": "测试游记"
}

查看数据库

178a84e765dba9a98a5532be87215654.jpeg
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BootDo是高效率,低封装,面向学习型,面向微服的开源JavaEE开发框架。 BootDo是在SpringBoot基础上搭建的一个Java基础开发平台,MyBatis为数据访问层,ApacheShiro为权限授权层,Ehcahe对常用数据进行缓存。 BootDo主要定位于后台管理系统学习交流,已内置后台管理系统的基础功能和高效的代码生成工具,包括:系统权限组件、数据权限组件、数据字典组件、核心工具组件、视图操作组件、工作流组件、代码生成等。前端界面风格采用了结构简单、性能优良、页面美观大气的TwitterBootstrap页面展示框架。采用分层设计、双重验证、提交数据安全编码、密码加密、访问验证、数据权限验证。使用Maven做项目管理,提高项目的易开发性、扩展性。 BootDo目前包括以下四大模块,系统管理(SYS)模块、内容管理(CMS)模块、在线办公(OA)模块、代码生成(GEN)模块。系统管理模块,包括企业组织架构(用户管理、机构管理、区域管理)、菜单管理、角色权限管理、字典管理等功能;内容管理模块,包括内容管理(文章、链接),栏目管理、站点管理、公共留言、文件管理、前端网站展示等功能;在线办公模块,提供简单的请假流程实例;代码生成模块,完成重复的工作。 BootDo提供了常用工具进行封装,包括日志工具、缓存工具、服务器端验证、数据字典、当前组织机构数据(用户、机构、区域)以及其它常用小工具等。另外还提供一个强大的在线代码生成工具。 内置功能: 用户管理用户是系统操作者,该功能主要完成系统用户配置。 机构管理:配置系统组织机构(公司、部门、小组),树结构展现,可随意调整上下级。 区域管理:系统城市区域模型,如:国家、省市、地市、区县的维护。 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 字典管理:对系统中经常使用的一些较为固定的数据进行维护,如:是否、男女、类别、级别等。 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 连接池监视:监视当期系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。 工作流引擎:实现业务工单流转、在线流程设计器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值