django中视图本质上就是个函数
,接受用户传入的请求,返回对应的响应。
在视图中处理业务逻辑。django约定将视图放在views.py
的文件中。这个文件应放在项目或者应用目录中。
基于函数的视图
def some_view(request):
dosometing
return HttpResponse(html)
特点:
基于类的视图,换了一种写法,不能替代函数视图,有一些优势:
所以后续大部分会采用类视图
的方式编写代码
注册需要前端发起一个携带需要注册的账号密码的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 {}
分步查看一下它都干了什么
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对象
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)
暂时了解它的功能就是去判断数据是否符合我们的规定即可
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的路径部分进行匹配,一旦匹配成功就导入并执行对应的视图来返回响应。
根路由
模块,就是项目文件目录下的urls.py文件。这个文件中定义了一个变量urlpatterns
。它应该是一个django.urls.path(),或者是django.urls.re_path()对象的列表。在根路由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": "测试游记"
}
发送请求
查看响应
{
"id": ,
"username": "zhongxin",
"email": "490336534@qq.com",
"mobile": "13000000000",
"name": "测试游记"
}
查看数据库