通过反向关系更新字段值。 Django 休息
Update field value through reverse relationship. Django REST
我正在使用 djangorestframework-simplejwt
进行身份验证。我的用例要求我使用 OTP 而不是密码。
为了存储 OTP,我创建了以下模型:
class OneTimePassword(models.Model):
otp = models.IntegerField()
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
用户模型:
class User(AbstractUser):
username = None
email = models.EmailField(_('email address'), unique=True)
country_code = models.IntegerField(default=91, max_length=3)
mobile = models.IntegerField(max_length=11, unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['mobile']
objects = CustomUserManager()
def __str__(self):
return f"{self.email},{self.mobile}"
我的计划是:
- POST
mobile
到 /api/generate_otp/
端点
- 在此端点的视图中,生成了一个新的 OTP 并存储在
OneTimePassword
模型中。 (用户由手机号决定)
- 在
api/token/obtain/
端点,OTP 和手机号码已发布。
- 如果 OTP 与存储在 OTP 模型中的值匹配,则返回 JWT 令牌。
我在 步骤 2 中遇到困难,即我无法通过用户更新 OneTimePassword 模型中的 OTP 值。
我试过以下方法:
class GenerateOTPMobileView(APIView):
permission_classes = ()
def post(self, request,):
mobile = request.data.get("mobile")
user = User.objects.get(mobile=mobile)
random_otp = randint(10000, 99999)
if user:
user.onetimepassword_set.otp = random_otp # This is not working
...
# send OTP through third party API
...
return Response({"success": "OTP sent to mobile number"},)
else:
return Response({"error": "Wrong Credentials"}, status=status.HTTP_400_BAD_REQUEST)
您正试图在关系的多边上设置 属性,但这种方式行不通。基本上,您只是在管理器上设置一个 属性,而管理器就像任何其他行为良好的 python 对象一样,只会在其自身上设置这个 属性 - 但它不会任何有用的东西。
相反,您应该 create()
一个新的 OTP 或 update()
一个特定的 OTP。
记住你的数据模型是这样的:
user:
- otp1
- otp2
- otp3
等等
所以没有“一个用户一个OTP”。为此,您需要一个 OneToOneField。
我正在使用 djangorestframework-simplejwt
进行身份验证。我的用例要求我使用 OTP 而不是密码。
为了存储 OTP,我创建了以下模型:
class OneTimePassword(models.Model):
otp = models.IntegerField()
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
用户模型:
class User(AbstractUser):
username = None
email = models.EmailField(_('email address'), unique=True)
country_code = models.IntegerField(default=91, max_length=3)
mobile = models.IntegerField(max_length=11, unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['mobile']
objects = CustomUserManager()
def __str__(self):
return f"{self.email},{self.mobile}"
我的计划是:
- POST
mobile
到/api/generate_otp/
端点 - 在此端点的视图中,生成了一个新的 OTP 并存储在
OneTimePassword
模型中。 (用户由手机号决定) - 在
api/token/obtain/
端点,OTP 和手机号码已发布。 - 如果 OTP 与存储在 OTP 模型中的值匹配,则返回 JWT 令牌。
我在 步骤 2 中遇到困难,即我无法通过用户更新 OneTimePassword 模型中的 OTP 值。
我试过以下方法:
class GenerateOTPMobileView(APIView):
permission_classes = ()
def post(self, request,):
mobile = request.data.get("mobile")
user = User.objects.get(mobile=mobile)
random_otp = randint(10000, 99999)
if user:
user.onetimepassword_set.otp = random_otp # This is not working
...
# send OTP through third party API
...
return Response({"success": "OTP sent to mobile number"},)
else:
return Response({"error": "Wrong Credentials"}, status=status.HTTP_400_BAD_REQUEST)
您正试图在关系的多边上设置 属性,但这种方式行不通。基本上,您只是在管理器上设置一个 属性,而管理器就像任何其他行为良好的 python 对象一样,只会在其自身上设置这个 属性 - 但它不会任何有用的东西。
相反,您应该 create()
一个新的 OTP 或 update()
一个特定的 OTP。
记住你的数据模型是这样的:
user:
- otp1
- otp2
- otp3
等等
所以没有“一个用户一个OTP”。为此,您需要一个 OneToOneField。