drf作业
作业:
1 自定义User表,新增mobile唯一约束字段;新增icon图片字段
2 在自定义User表基础上,用 GenericViewSet + CreateModelMixin + serializer 完成User表新增接口(就是注册接口)(重要提示:序列化类要重写create方法,不然密码就是明文了)
3 在自定义User表基础上,用 GenericViewSet + RetrieveModelMixin + serializer 完成User表单查(就是用户中心)
4 在自定义User表基础上,用 GenericViewSet + UpdateModelMixin + serializer 完成用户头像的修改
代码:
models.py
from django.db import models # Create your models here. from django.contrib.auth.models import AbstractUser class User(AbstractUser): mobile=models.CharField(max_length=32,unique=True) #唯一 icon=models.ImageField(upload_to='icon',default='icon/default.png') #需要配media文件夹,上传的文件就会放到media文件夹下的icon class Book(models.Model): name = models.CharField(max_length=64) def __str__(self): return self.name class Car(models.Model): name = models.CharField(max_length=64) def __str__(self): return self.name
settings.py
MEDIA_URL='/media/' MEDIA_ROOT=os.path.join(BASE_DIR,'media') #真正的文件夹路径 #指定使用的auth表是自己定义的 AUTH_USER_MODEL='api.User' #app名.表名
总路由
from django.contrib import admin from django.urls import path,re_path,include from django.views.static import serve # 暴露接口使用 from django.conf import settings # 以后都用这个导配置文件,暴露接口 urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('api.urls')), re_path(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}) ]
api/urls.py
from django.urls import path,re_path,include from api import views from rest_framework.routers import SimpleRouter router = SimpleRouter() router.register('users', views.UserView,'users') # 可以注册很多 urlpatterns = [ # path('users/', views.UserView.as_view(action={'post':'create'})), # 有问题 path('', include(router.urls)), # 第二种方式 # 暴露后端指定文件夹资源,这样就会把files暴露给外界 ] # urlpatterns+=router.urls # 一种方式
views.py
from django.shortcuts import render from rest_framework.viewsets import GenericViewSet # ViewSetMixin:重写了as_view,路由配置变样了, generics.GenericAPIView:只需要配俩东西 from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin, UpdateModelMixin from api import models from api import ser # Create your views here. class UserView(GenericViewSet, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin): queryset = models.User.objects.all() serializer_class = ser.UserModelSerializer # 假设get请求和post请求,用的序列化类不一样,如何处理? # 重写getget_serializer_class,返回啥,用的序列号类就是啥 # 注册,用的序列化类是UserModelSerializer,查询一个用的序列化类是UserReadOnlyModelSerializer def get_serializer_class(self): print(self.action) # create,retrieve if self.action == 'create': return ser.UserModelSerializer elif self.action == 'retrieve': return ser.UserReadOnlyModelSerializer elif self.action == 'update': return ser.UserImageModelSerializer
ser.py
from rest_framework import serializers from api import models from rest_framework.exceptions import ValidationError class UserModelSerializer(serializers.ModelSerializer): re_password = serializers.CharField(max_length=16, min_length=4, required=True, write_only=True) # 因为re_password在表中没有,需要在这定义 class Meta: model = models.User fields = ['username', 'password', 'mobile', 're_password', 'icon'] extra_kwargs = { 'username': {'max_length': 16}, 'password': {'write_only': True} } # 局部钩子 def validate_mobile(self, data): if not len(data) == 11: raise ValidationError('手机号不合法') return data # 全局钩子 def validate(self, attrs): if not attrs.get('password') == attrs.get('re_password'): raise ValidationError('两次密码不一致') attrs.pop('re_password') # 剔除该字段,因为数据库没有这个字段 return attrs def create(self, validated_data): # attrs.pop('re_password') 如果上面没有剔除,在这也可以 # models.User.objects.create(**validated_data) 这个密码不会加密 user = models.User.objects.create_user(**validated_data) return user class UserReadOnlyModelSerializer(serializers.ModelSerializer): class Meta: model = models.User fields = ['username', 'icon'] class UserImageModelSerializer(serializers.ModelSerializer): class Meta: model = models.User fields = ['icon']
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步