通过反向关系更新字段值。 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}"

我的计划是:

  1. POST mobile/api/generate_otp/ 端点
  2. 在此端点的视图中,生成了一个新的 OTP 并存储在 OneTimePassword 模型中。 (用户由手机号决定)
  3. api/token/obtain/ 端点,OTP 和手机号码已发布。
  4. 如果 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。