From e634c2d4d88fe3a59369896216e97b7b9f987086 Mon Sep 17 00:00:00 2001 From: winkidney Date: Tue, 3 Dec 2019 13:22:18 +0800 Subject: [PATCH] Feature: Add user-creation for UserViewSet --- core/serializers.py | 12 +--------- core/views.py | 16 ------------- users/serializers.py | 54 ++++++++++++++++++++++++++++++++++++++++++++ users/urls.py | 5 ++-- users/views.py | 46 +++++++++++++++++++++---------------- 5 files changed, 83 insertions(+), 50 deletions(-) create mode 100644 users/serializers.py diff --git a/core/serializers.py b/core/serializers.py index 22f37c3..ab191ec 100644 --- a/core/serializers.py +++ b/core/serializers.py @@ -6,17 +6,7 @@ from taggit.models import Tag from core.models import Image, Board from core.models import Pin from django_images.models import Thumbnail -from users.models import User - - -class UserSerializer(serializers.HyperlinkedModelSerializer): - class Meta: - model = User - fields = ( - 'username', - 'gravatar', - settings.DRF_URL_FIELD_NAME, - ) +from users.serializers import UserSerializer class ThumbnailSerializer(serializers.HyperlinkedModelSerializer): diff --git a/core/views.py b/core/views.py index 8d2b47d..3ba1a03 100644 --- a/core/views.py +++ b/core/views.py @@ -6,21 +6,6 @@ from rest_framework.viewsets import GenericViewSet from core import serializers as api from core.models import Image, Pin, Board from core.permissions import IsOwnerOrReadOnly -from users.models import User - - -class UserViewSet( - mixins.RetrieveModelMixin, - mixins.ListModelMixin, - GenericViewSet, -): - serializer_class = api.UserSerializer - pagination_class = None - - def get_queryset(self): - if self.request.user.is_anonymous: - return User.objects.none() - return User.objects.filter(id=self.request.user.id) class ImageViewSet(mixins.CreateModelMixin, GenericViewSet): @@ -52,7 +37,6 @@ class BoardViewSet(viewsets.ModelViewSet): drf_router = routers.DefaultRouter() -drf_router.register(r'users', UserViewSet, base_name="user") drf_router.register(r'pins', PinViewSet) drf_router.register(r'images', ImageViewSet) drf_router.register(r'boards', BoardViewSet) diff --git a/users/serializers.py b/users/serializers.py new file mode 100644 index 0000000..be38dc4 --- /dev/null +++ b/users/serializers.py @@ -0,0 +1,54 @@ +from django.conf import settings +from rest_framework import serializers +from rest_framework.exceptions import ValidationError + +from users.models import User + + +class UserSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = User + fields = ( + 'username', + 'email', + 'gravatar', + 'password', + 'password_repeat', + settings.DRF_URL_FIELD_NAME, + ) + extra_kwargs = { + settings.DRF_URL_FIELD_NAME: { + "view_name": "users:user-detail", + }, + } + + password = serializers.CharField( + write_only=True, + required=True, + allow_blank=False, + min_length=6, + max_length=32, + ) + password_repeat = serializers.CharField( + write_only=True, + required=True, + allow_blank=False, + min_length=6, + max_length=32, + ) + + def create(self, validated_data): + if validated_data['password'] != validated_data['password']: + raise ValidationError( + detail={ + "password_repeat": "Tow password doesn't match", + } + ) + validated_data.pop('password_repeat') + password = validated_data.pop('password') + user = super(UserSerializer, self).create( + validated_data, + ) + user.set_password(password) + user.save() + return user diff --git a/users/urls.py b/users/urls.py index 6b7aa5b..5ec6619 100644 --- a/users/urls.py +++ b/users/urls.py @@ -1,11 +1,10 @@ -from django.conf.urls import url +from django.conf.urls import url, include from users.views import login_user from . import views urlpatterns = [ - url(r'^private/$', views.private, name='private'), - url(r'^register/$', views.CreateUser.as_view(), name='register'), + url(r'', include(views.drf_router.urls)), url(r'^login/$', login_user, name='login'), url(r'^logout/$', views.logout_user, name='logout'), ] diff --git a/users/views.py b/users/views.py index f4d5a8a..d16163e 100644 --- a/users/views.py +++ b/users/views.py @@ -10,7 +10,10 @@ from django.http import HttpResponseRedirect, HttpResponseBadRequest, HttpRespon from django.template.response import TemplateResponse from django.utils.functional import lazy from django.views.generic import CreateView +from rest_framework import mixins, routers +from rest_framework.permissions import BasePermission from rest_framework.renderers import JSONRenderer +from rest_framework.viewsets import GenericViewSet from core.serializers import UserSerializer from .forms import UserCreationForm @@ -21,26 +24,29 @@ def reverse_lazy(name=None, *args): return lazy(reverse, str)(name, args=args) -class CreateUser(CreateView): - template_name = 'users/register.html' - model = User - form_class = UserCreationForm - success_url = reverse_lazy('core:recent-pins') +class UserViewSet( + mixins.RetrieveModelMixin, + mixins.ListModelMixin, + mixins.CreateModelMixin, + GenericViewSet, +): + class Permission(BasePermission): + def has_permission(self, request, view): + if not request.method == "POST": + return True + return settings.ALLOW_NEW_REGISTRATIONS - def get(self, request, *args, **kwargs): - if not settings.ALLOW_NEW_REGISTRATIONS: - messages.error(request, "The admin of this service is not allowing new registrations.") - return HttpResponseRedirect(reverse('core:recent-pins')) - return super(CreateUser, self).get(request, *args, **kwargs) + def has_object_permission(self, request, view, obj): + return request.user == obj - def form_valid(self, form): - redirect = super(CreateUser, self).form_valid(form) - permissions = Permission.objects.filter(codename__in=['add_pin', 'add_image']) - user = authenticate(username=form.cleaned_data['username'], - password=form.cleaned_data['password']) - user.user_permissions = permissions - login(self.request, user) - return redirect + permission_classes = [Permission, ] + serializer_class = UserSerializer + pagination_class = None + + def get_queryset(self): + if self.request.user.is_anonymous: + return User.objects.none() + return User.objects.filter(id=self.request.user.id) def login_user(request): @@ -83,5 +89,5 @@ def logout_user(request): return HttpResponseRedirect(reverse('core:recent-pins')) -def private(request): - return TemplateResponse(request, 'users/private.html', None) +drf_router = routers.DefaultRouter() +drf_router.register(r'users', UserViewSet, base_name="user")