使用 CustomUserModel 扩展默认用户模型和 API 类 修改来自 Django REST API 的响应
Modify response from Django REST API using CustomUserModel extending default User Model and API classes
我有一个带有 CustomUserModel 的 Django 项目。我已经用我的 CustomRegisterView 扩展了 Django 默认的 RegisterView,并且还通过扩展 LoginView 创建了 CustomLoginView。
一切正常,数据也与自定义字段一起保存,在登录和注册时,我得到一个 "key" 作为响应,但我想使用主键值和主键值等附加字段自定义这两个 API 的响应result_flag 将为 0 或 1。
我的 CustomRegisterSerializer class 定义为-
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
查看文件:
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:(在应用程序目录中)
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())
]
更新1:
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())
有什么方法可以获得自定义回复吗?
如果覆盖 REST_AUTH_SERIALIZERS 的默认设置,则可以为响应应用自定义视图。
例如,在您的 settings.py 文件中,您必须定义 REST_AUTH_SERIALIZERS
字典。
#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
}
经过大量搜索和应用各种测试,我终于找到了解决问题的方法。
通过在 Django 用户模型中使用自定义模型和自定义序列化程序,我们可以完全自定义我们应用逻辑的 views.py 文件。
下面是我在 views.py 文件中所做的更改:
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 文件:
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
**欢迎提出改进和建议。
我有一个带有 CustomUserModel 的 Django 项目。我已经用我的 CustomRegisterView 扩展了 Django 默认的 RegisterView,并且还通过扩展 LoginView 创建了 CustomLoginView。 一切正常,数据也与自定义字段一起保存,在登录和注册时,我得到一个 "key" 作为响应,但我想使用主键值和主键值等附加字段自定义这两个 API 的响应result_flag 将为 0 或 1。
我的 CustomRegisterSerializer class 定义为-
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
查看文件:
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:(在应用程序目录中)
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())
]
更新1:
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())
有什么方法可以获得自定义回复吗?
如果覆盖 REST_AUTH_SERIALIZERS 的默认设置,则可以为响应应用自定义视图。
例如,在您的 settings.py 文件中,您必须定义 REST_AUTH_SERIALIZERS
字典。
#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
}
经过大量搜索和应用各种测试,我终于找到了解决问题的方法。
通过在 Django 用户模型中使用自定义模型和自定义序列化程序,我们可以完全自定义我们应用逻辑的 views.py 文件。
下面是我在 views.py 文件中所做的更改:
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 文件:
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
**欢迎提出改进和建议。