• 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
    from api import models
    from api import ser
    
    
    # Create your views here.
    class UserView(GenericViewSet, CreateModelMixin, RetrieveModelMixin):
        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']
  • 相关阅读:
    队列加分项
    队列课下作业
    20162306 2017-2018-1 《程序设计与数据结构》第7周学习总结
    20162306 2017-2018-1 《程序设计与数据结构》第5周学习总结
    20162306陈是奇 第一次实验报告
    20162306 2017-2018-1 《程序设计与数据结构》第3周学习总结
    20162306 陈是奇 2017-2018-1 《程序设计与数据结构》第1周学习总结
    数据库实验补充
    2017-2018-1 20162304 实验二 树
    队列加分项
  • 原文地址:https://www.cnblogs.com/baicai37/p/13307783.html
Copyright © 2020-2023  润新知