click register
new user chuanshuoge registered
login as chuanshuoge
create a new post
#django/api/apiviewfrom music.models import Album, Song
from music.api.serializers import MusicSerializer, UserSerializer, SongSerializer, PasswordSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.http import Http404
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from rest_framework.decorators import authentication_classes, permission_classes
from django.contrib.auth.password_validation import validate_password
from django.core import exceptions
class AlbumList(APIView):
def get(self, request, format=None):
username = request.GET.get('author')
data_length = request.GET.get('data_length')
#filter by author
if username==None:
albums = Album.objects.all()
else:
author_id = get_object_or_404(User, username=username).pk
albums = Album.objects.filter(author=author_id).order_by('-date_posted')
#filter by data length
if data_length!=None:
try:
int(data_length)
except ValueError:
return Response('data length is invvalid', status=status.HTTP_406_NOT_ACCEPTABLE)
else:
albums = albums[:int(data_length)]
serializer = MusicSerializer(albums, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = MusicSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class AlbumDetail(APIView):
def get_object(self, pk):
try:
return Album.objects.get(pk=pk)
except Album.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
album = self.get_object(pk)
serializer = MusicSerializer(album)
return Response(serializer.data)
def put(self, request, pk, format=None):
album = self.get_object(pk)
#only owner can edit
if album.author != request.user:
return Response({"detail": "You do not have permission to perform this action."},
status= status.HTTP_403_FORBIDDEN)
serializer = MusicSerializer(album, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
album = self.get_object(pk)
# only owner can delete
if album.author != request.user:
return Response({"detail": "You do not have permission to perform this action."},
status=status.HTTP_403_FORBIDDEN)
album.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class UserList(APIView):
def get(self, request, format=None):
users = User.objects.all()
serializer = UserSerializer(users, many=True)
return Response(serializer.data)
@authentication_classes([])
@permission_classes([])
class UserRegister(APIView):
def post(self, request, format=None):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
#email has to be unique
email = request.POST.get('email')
unique_email = User.objects.filter(email=email).count()
if(unique_email > 0):
return Response({'email': 'email already exist'}, status=status.HTTP_406_NOT_ACCEPTABLE)
#validate password
password = request.POST.get('password')
try:
validate_password(password)
except exceptions.ValidationError as e:
return Response(e.messages, status=status.HTTP_406_NOT_ACCEPTABLE)
else:
pass
#register new user
serializer.save()
#set password for new user
username = serializer.data.get('username')
newUser = User.objects.get(username=username)
newUser.set_password(password)
#save password for new user
newUser.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class SongList(APIView):
def get(self, request, format=None):
songs = Song.objects.all()
serializer = SongSerializer(songs, many=True)
return Response(serializer.data)
class UpdatePassword(APIView):
def get_object(self, queryset=None):
return self.request.user
def put(self, request, *args, **kwargs):
currentUser = self.get_object()
serializer = PasswordSerializer(data=request.data)
if serializer.is_valid():
# Check old password
old_password = serializer.data.get("old_password")
if not currentUser.check_password(old_password):
return Response({"old_password": ["Wrong password."]},
status=status.HTTP_400_BAD_REQUEST)
# set_password also hashes the password that the user will get
currentUser.set_password(serializer.data.get("new_password"))
currentUser.save()
return Response(status=status.HTTP_204_NO_CONTENT)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
-----------------------------
#django/api/serializers
from rest_framework import serializers
from django.contrib.auth.models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email')
----------------------------------
#django/api/urls
from django.urls import path
from music.api import apiview
from rest_framework.authtoken import views
app_name = 'musicAPI'
urlpatterns = [
...
path('user_register/', apiview.UserRegister.as_view(), name='UserRegister'),
]
----------------------------------------
//react/pages/registerUser
import React, { Component } from 'react';
import '../App.css';
import { registerUser } from '../redux/actions/registerUser';
import { connect } from 'react-redux';
import { Input } from 'antd';
import { Button } from 'reactstrap';
import { MdEmail, MdAccessibility } from "react-icons/md";
import { Fa500Px } from "react-icons/fa";
class RegisterUser extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
username: '',
password: '',
};
}
inputChange = (e, p) => {
this.setState({ [p]: e.target.value });
}
formSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
formData.set('email', this.state.email);
formData.set('username', this.state.username);
formData.set('password', this.state.password);
this.props.dispatch(registerUser(formData));
}
render() {
return (
<form style={{ marginLeft: '10px', width: '300px' }}
onSubmit={(e) => this.formSubmit(e)}>
<legend>Register User</legend>
<hr />
<p style={{ color: 'red' }}>{this.props.error}</p>
{this.props.registered ? <p style={{ color: 'green' }}>Registration success</p> : null}
<Input placeholder="username" required='required'
prefix={<MdAccessibility style={{ color: 'rgba(0,0,0,.25)' }} />}
onChange={(e) => this.inputChange(e, 'username')}
style={{ marginTop: '5px' }}
/>
<Input placeholder="email" required='required' type='email'
prefix={<MdEmail style={{ color: 'rgba(0,0,0,.25)' }} />}
onChange={(e) => this.inputChange(e, 'email')}
style={{ marginTop: '15px' }}
/>
<Input.Password placeholder="password" required='required'
prefix={<Fa500Px style={{ color: 'rgba(0,0,0,.25)' }} />}
onChange={(e) => this.inputChange(e, 'password')}
style={{ marginTop: '15px' }}
/>
<Button color="success" type='submit' size='sm'
style={{ marginTop: '15px' }}
>Submit</Button>
</form>
);
}
}
export default connect(
(store) => {
return {
registered: store.users.registered,
error: store.users.error
};
}
)(RegisterUser);
--------------------------------------
//redux/actions/registerUser
import axios from 'axios';
export function registerUser(data) {
return {
type: "register_user",
payload: axios({
method: 'post',
url: 'http://127.0.0.1:8000/api/user_register/',
data: data,
})
}
}
--------------------------------
//redux/reducers/userReducer
export default function reducer(
state = {
users: [],
fetching: false,
fetched: false,
registering: false,
registered: false,
error: ''
},
action
) {
switch (action.type) {
case "fetch_users_PENDING": {
return { ...state, fetching: true, fetched: false }
}
case "fetch_users_FULFILLED": {
return {
...state,
fetching: false,
fetched: true,
users: action.payload.data,
error: ''
}
}
case "fetch_users_REJECTED": {
return {
...state,
fetching: false,
error: action.payload.toString()
}
}
case "register_user_PENDING": {
return { ...state, registering: true, registered: false, error: '' }
}
case "register_user_FULFILLED": {
return {
...state,
registering: false,
registered: true,
error: ''
}
}
case "register_user_REJECTED": {
return {
...state,
registering: false,
error: JSON.stringify(action.payload.response.data),
}
}
default:
break;
}
return state;
}
//react/pages/registerUser
import React, { Component } from 'react';
import '../App.css';
import { registerUser } from '../redux/actions/registerUser';
import { connect } from 'react-redux';
import { Input } from 'antd';
import { Button } from 'reactstrap';
import { MdEmail, MdAccessibility } from "react-icons/md";
import { Fa500Px } from "react-icons/fa";
class RegisterUser extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
username: '',
password: '',
};
}
inputChange = (e, p) => {
this.setState({ [p]: e.target.value });
}
formSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
formData.set('email', this.state.email);
formData.set('username', this.state.username);
formData.set('password', this.state.password);
this.props.dispatch(registerUser(formData));
}
render() {
return (
<form style={{ marginLeft: '10px', width: '300px' }}
onSubmit={(e) => this.formSubmit(e)}>
<legend>Register User</legend>
<hr />
<p style={{ color: 'red' }}>{this.props.error}</p>
{this.props.registered ? <p style={{ color: 'green' }}>Registration success</p> : null}
<Input placeholder="username" required='required'
prefix={<MdAccessibility style={{ color: 'rgba(0,0,0,.25)' }} />}
onChange={(e) => this.inputChange(e, 'username')}
style={{ marginTop: '5px' }}
/>
<Input placeholder="email" required='required' type='email'
prefix={<MdEmail style={{ color: 'rgba(0,0,0,.25)' }} />}
onChange={(e) => this.inputChange(e, 'email')}
style={{ marginTop: '15px' }}
/>
<Input.Password placeholder="password" required='required'
prefix={<Fa500Px style={{ color: 'rgba(0,0,0,.25)' }} />}
onChange={(e) => this.inputChange(e, 'password')}
style={{ marginTop: '15px' }}
/>
<Button color="success" type='submit' size='sm'
style={{ marginTop: '15px' }}
>Submit</Button>
</form>
);
}
}
export default connect(
(store) => {
return {
registered: store.users.registered,
error: store.users.error
};
}
)(RegisterUser);
--------------------------------------
//redux/actions/registerUser
import axios from 'axios';
export function registerUser(data) {
return {
type: "register_user",
payload: axios({
method: 'post',
url: 'http://127.0.0.1:8000/api/user_register/',
data: data,
})
}
}
--------------------------------
//redux/reducers/userReducer
export default function reducer(
state = {
users: [],
fetching: false,
fetched: false,
registering: false,
registered: false,
error: ''
},
action
) {
switch (action.type) {
case "fetch_users_PENDING": {
return { ...state, fetching: true, fetched: false }
}
case "fetch_users_FULFILLED": {
return {
...state,
fetching: false,
fetched: true,
users: action.payload.data,
error: ''
}
}
case "fetch_users_REJECTED": {
return {
...state,
fetching: false,
error: action.payload.toString()
}
}
case "register_user_PENDING": {
return { ...state, registering: true, registered: false, error: '' }
}
case "register_user_FULFILLED": {
return {
...state,
registering: false,
registered: true,
error: ''
}
}
case "register_user_REJECTED": {
return {
...state,
registering: false,
error: JSON.stringify(action.payload.response.data),
}
}
default:
break;
}
return state;
}
reference:
https://stackoverflow.com/questions/27085219/how-can-i-disable-authentication-in-django-rest-framework
https://stackoverflow.com/questions/36414804/integrate-django-password-validators-with-django-rest-framework-validate-passwor
https://stackoverflow.com/questions/17312831/what-does-request-user-refer-to-in-django
No comments:
Post a Comment