I have a Django Project with CustomUserModel. I have extended Django default RegisterView with my CustomRegisterView, and also created CustomLoginView by extending LoginView. Everything works fine, data too get saved with custom fields, and while loging in and registering, I get a "key" in response, but I want to customize response of both the APIs with additional fields such as primary key value and a result_flag which will be either 0 or 1.
My CustomRegisterSerializer class is defined as-
class CustomRegisterSerializer(RegisterSerializer):
email = serializers.EmailField()
password1 = serializers.CharField(write_only=True)
name = serializers.CharField()
phone_no = serializers.IntegerField()
user_android_id = serializers.CharField()
user_fcm_token = serializers.CharField(required=True)
user_social_flag = serializers.IntegerField()
user_fb_id = serializers.CharField(required=True)
user_android_app_version = serializers.CharField()
class Meta:
model = User
fields = ('email', 'name', 'phone_no', 'user_android_id', 'user_fcm_token',
'user_social_flag', 'user_fb_id', 'user_android_app_version')
def get_cleaned_data(self):
super(CustomRegisterSerializer, self).get_cleaned_data()
return {
'password1': self.validated_data.get('password1', ''),
'email': self.validated_data.get('email', ''),
'phone_no': self.validated_data.get('phone_no'),
'name': self.validated_data.get('name'),
'user_android_id': self.validated_data.get('user_android_id'),
'user_fcm_token': self.validated_data.get('user_fcm_token'),
'user_social_flag': self.validated_data.get('user_social_flag'),
'user_fb_id': self.validated_data.get('user_fb_id'),
'user_android_app_version': self.validated_data.get('user_android_app_version'),
}
def save(self, request):
user = super(CustomRegisterSerializer, self).save(request)
print(user.pk)
return user
Views file:
from rest_auth.registration.views import RegisterView, LoginView
from app.models import User
class CustomRegisterView(RegisterView):
queryset = User.objects.all()
class CustomLoginView(LoginView):
queryset = User.objects.all()
urls.py: (In apps directory)
from django.urls import re_path
from . import views
app_name = 'app'
urlpatterns = [
re_path(r'^registration/$', views.CustomRegisterView.as_view()),
re_path(r'^user-login/$', views.CustomLoginView.as_view())
]
UPDATE1:
Could I modify this LoginApi view with CustomUserModel, and use authenticate() method for authentication of email and password.
class AuthUserLogin(CsrfExemptMixin, View):
def post(self, request):
password = "" if request.POST['user_password'] == "" else request.POST['user_password']
email = "" if request.POST['user_email'] == "" else request.POST['user_email']
android_id = "" if request.POST['user_android_id'] == "" else request.POST['user_android_id']
fcm_token = "" if request.POST['user_fcm_token'] == "" else request.POST['user_fcm_token']
social_flag = "" if request.POST['user_social_flag'] == "" else request.POST['user_social_flag']
u_name = "" if request.POST['user_name'] == "" else request.POST['user_name']
fb_id = "" if request.POST['user_fb_id'] == "" else request.POST['user_fb_id']
hash_pwd = pbkdf2_sha256.using(rounds=8000, salt=str.encode(SALT_KEY)).hash(password)
result_response = ""
if social_flag == "0":
email_check = UserAuth.objects.filter(email_id=email)
if email_check.exists():
authenticate_user = UserAuth.objects.filter(email_id=email,password=hash_pwd).values('user_id')
if authenticate_user.exists():
u_id = authenticate_user[0]['user_id']
num_rows = UserAuth.objects.filter(user_id=u_id).update(user_android_id=android_id,
user_fcm_token= fcm_token,
user_social_flag=social_flag,
user_fb_id=fb_id)
if num_rows > 0:
result_response = {
'result': 1,
'user_id' : u_id,
}
else:
result_response = {
'result': 0,
'msg' : "You have entered an incorrect password for the e-mail id: " + str(email)
}
else:
print("email not exists")
result_response = {
'result' : 0,
'msg' :"User with this e-mail address is not registered with nifty trader"
}
elif social_flag == "1" or email != "":
##------- check email already exists
check_email = UserAuth.objects.filter(email_id=email).values('user_id')
if check_email.exists():
print("email exists social user")
#print(check_email[0]['user_id'])
update_record = UserAuth.objects.filter(user_id=check_email[0]['user_id'])\
.update(user_android_id=android_id,
user_fcm_token=fcm_token,
user_social_flag=social_flag,
password=None,
user_name=u_name, user_fb_id=fb_id)
if update_record == 0 or update_record == "" or update_record is None :
result_response = {'result': 0}
else:
result_response = {
'result': 1,
'user_id': check_email[0]['user_id'],
}
else:
print("email does not exists")
save_user = UserAuth(user_android_id=android_id,email_id=email,
user_fcm_token=fcm_token,
user_social_flag=social_flag,
password="", created_at=date.today(), user_name=u_name,
user_fb_id=fb_id)
save_user.save()
if save_user.pk == "" or save_user.pk is None:
result_response = {'result': 0}
else:
result_response = {
'result': 1,
'user_id': save_user.pk,
}
elif social_flag == "2":
print("fb login")
check_fbid = UserAuth.objects.filter(user_fb_id=fb_id).values('user_id')
if check_fbid.exists():
print("fb id exists ")
update_record = UserAuth.objects.filter(user_id=check_fbid[0]['user_id'])\
.update(user_android_id=android_id,
user_fcm_token=fcm_token,
user_social_flag=social_flag,
password=None,
user_name=u_name,
email_id=email)
if update_record == 0 or update_record == "" or update_record is None :
result_response = {'result': 0}
else:
result_response = {
'result': 1,
'user_id': check_fbid[0]['user_id'],
}
else:
save_fbuser = UserAuth(user_android_id=android_id, email_id=email,
user_fcm_token=fcm_token,
user_social_flag=social_flag,
password="", created_at=date.today(), user_name=u_name,
user_fb_id=fb_id)
save_fbuser.save()
if save_fbuser.pk == "" or save_fbuser.pk is None:
result_response = {'result': 0}
else:
result_response = {
'result': 1,
'user_id': save_fbuser.pk,
}
return JsonResponse(result_response, safe=False)
user_auth = csrf_exempt(AuthUserLogin.as_view())
Is there any way I could get a custom response?
If you override the default setting of the REST_AUTH_SERIALIZERS, you can apply a custom view for the response.
For example, in your settings.py file you must define REST_AUTH_SERIALIZERS
dict.
#serializers.py
class MyUserSerializer(serializers.ModelSerializer):
class Meta:
model = UserModel
fields = ('pk', 'username', 'email', 'first_name', 'last_name',
'phone_no', 'user_android_id' )
read_only_fields = ('email', )
#settings.py
"REST_AUTH_SERIALIZERS" : {
"USER_DETAILS_SERIALIZER": MyUserSerializer
}
After alot of searching and applying various tests, I finally found the solution to my problem.
By using Custom model and Custom Serializer in Django User model, We could fully customize the views.py file where we apply our logic.
So below is the change I did in my views.py file:
from rest_framework.authtoken.models import Token
from app.serializers import MyUserSerializer
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
class CustomRegisterView(APIView):
"""
User Registration API
"""
def post(self, request):
serializer = MyUserSerializer(data=request.data)
if serializer.is_valid():
user = serializer.save()
if user:
token = Token.objects.create(user=user)
# json = serializer.data
# json['token'] = token.key
response = {
'result': 1,
'key': token.key
'user_id': user.pk
}
return Response(response, status=status.HTTP_201_CREATED)
# json = serializer.errors
response = {
'result':0,
'msg':"User with email is already registered."
}
return Response(response, status=status.HTTP_400_BAD_REQUEST)
serializers.py file:
from app.models import User
from rest_framework import serializers
class MyUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'password', 'name', 'phone_no','created_at', 'user_android_id',
'user_fcm_token','user_social_flag', 'user_fb_id', 'user_android_app_version')
def create(self, validated_data):
user = User.objects.create_user(**validated_data)
return user
**Improvements and suggestions are welcomed.
来源:https://stackoverflow.com/questions/53319843/modify-response-from-django-rest-api-using-customusermodel-extending-default-use