10、DRF框架作业
1) 账号、手机号、邮箱 多方式登录
urlpatterns = [ url(r'^user/center/$', views.UserCenterViewSet.as_view({'get':'user_center'})) ] class LoginSerializer(serializers.ModelSerializer): username = serializers.CharField() class Meta: model = models.User fields =('username', 'password') def validate(self, attrs): user = self._get_user(attrs) payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) self.context['token'] = token return attrs def _get_user(self, attrs): username = attrs.get('username') password = attrs.get('password') import re if re.match(r'^1[3-9][0-9]{9}$', username): user = models.User.objects.filter(mobile=username, is_active=True).first() elif re.match(r'^.+@.+$', username): user = models.User.objects.filter(email=username, is_active=True).first() else: user = models.User.objects.filter(username=username, is_active=True).first() if user and user.check_password(password): return user raise ValidationError({'user': 'user or password error'}) class LoginViewSet(ViewSet): authentication_classes = [] permission_classes = [] def login(self, request, *args, **kwargs): serializer = serializers.LoginSerializer(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) token = serializer.context.get('token') return Response({'token': token})
2) 创建一个vip用户
router.register('cars', views.CarViewSet, 'car') class CarSerializer(serializers.ModelSerializer): class Meta: model = models.Car fields = ['name'] from django.contrib.auth.models import Group from rest_framework.permissions import BasePermission class IsVipUser(BasePermission): def has_permission(self, request, view): if request.user and request.user.is_authenticated: try: vip_group = Group.objects.get(name='vip') if vip_group in request.user.groups.all(): return True except: pass return False class CarViewSet(ModelViewSet): permission_classes = [IsVipUser] queryset = models.Car.objects.all() serializer_class = serializers.CarSerializer
3) 完成一个修改头像的接口,自定义权限类,只有vip用户才可以完成头像的修改
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/' 主路由 urlpatterns = [ url(r'^media/(?P<path>).*$', serve, {'document_root': settings.MEDIA_ROOT}) ] 子路由 router.register('user/image', views.IconViewSet, 'image') class IconSerializer(serializers.ModelSerializer): class Meta: model = models.User fields = ['icon'] class IconViewSet(GenericViewSet, mixins.UpdateModelMixin): permission_classes = [IsVipUser] queryset = models.User.objects.filter(is_active=True).all() serializer_class = serializers.IconSerializer
4) 自定义频率类,达到用户一天最多只能修改一次头像
url('^user/icon/$', views.IconViewSet.as_view({'patch': 'my_patch'})), REST_FRAMEWORK = { 'DEFAULT_THROTTLE_RATES': { 'icon': '1/day', }, } class IconRateThrottle(SimpleRateThrottle): scope = 'icon' def get_cache_key(self, request, view): if request.user.is_authenticated: ident = request.user.pk else: ident = self.get_ident(request) return self.cache_format % {'scope': self.scope, 'ident': ident} class IconViewSet(GenericViewSet, mixins.UpdateModelMixin): permission_classes = [IsVipUser] throttle_classes = [IconRateThrottle] queryset = models.User.objects.filter(is_active=True).all() serializer_class = serializers.IconSerializer def my_patch(self, request, *args, **kwargs): serializer = serializers.IconSerializer(instance=request.user, data=request.data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data)
5)用ModelViewSet类和SimpleRouter类,完成六大基础接口(删除用is_delete字段完成)
url.py router = SimpleRouter() router.register('v1/cars', views.CarModelView, 'car') urlpatterns = [ url('', include(router.urls)) ] views.py class CarModelView(ModelViewSet): queryset = models.Car.objects.filter(is_delete=False).all() serializer_class = serializers.CarModelSerizlizer def destory(self, request, *args, **kwargs): pk = kwargs.get('pk') models.Car.objects.filter(is_delete=False, pk=pk).update(is_delete=True) return Response(status=204)
6)采用 GenericViewSet + mixins 自定义组合八个接口(不要delete的两个接口)
router.py class SimpleRouter(DjangoSimpleRouter): routes = [ Route( mapping={ 'get':'list', 'post': 'create', 'delete': 'mutiple_destory', 'put': 'mutiple_update', 'patch': 'multiple_partial_update' }) ] url.py router = SimpleRouter() router.register('v2/cars', views.CarViewSet, 'car') views.py class CarViewSet(GenericViewSet,RetrieveModelMixin,CreateModelMixin, UpdateModelMixin,ListModelMixin): queryset = models.Car.objects.filter(is_delete=False).all() serializer_class = serializers.CarModelSerizlizer
7)自定义User表,新增mobile唯一约束字段;新增icon图片字段
models.py class User(AbstractUser): mobile = model.CharField(max_length=11, unique=True) icon = model.ImageField(upload_to='icon', default='icon/default.png') def __str__(self): return self.username settings.py AUTH_USER_MODEL = 'api.User'
8)创建Book表、Publish表、建立Author表关系
from django.db import models class Book(models.Model): name = models.CharField(max_length=64) price = models.DecimalField(max_digits=5, decimal_places=2, default=0) publish = models.ForeignKey(to='Publish') authors = models.ManyToManyField(to='Author') def __str__(self): return self.name @property def publish_name(self): return self.publish.name @property def author_list(self): temp_author_list = [] for author in self.authors.all(): author_dic = { "name": author.name, "gender": author.get_sex_display() } temp_author_list.append(author_dic) return temp_author_list class Publish(models.Model): name = models.CharField(max_length=64) def __str__(self): return self.name class Author(models.Model): SEX_CHOICES = ((0, '男'), (1, '女')) name = models.CharField(max_length=64, verbose_name='姓名') sex = models.IntegerField(choices=SEX_CHOICES, default=0) def __str__(self): return self.name
1
1

浙公网安备 33010602011771号