【问题标题】:Update field value through reverse relationship. Django REST通过反向关系更新字段值。 Django 休息
【发布时间】:2020-07-22 18:19:31
【问题描述】:

我正在使用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)

【问题讨论】:

  • 它可能工作得很好,但是你在拯救用户吗?等等,你正在分配一个反向关系......如果这是 Django 2,它会被默默地忽略。使用these methods
  • @Melvyn 我不知道该怎么做。另外,我不是在创建新用户,而是在更新 OTP 值
  • @Melvyn 任何帮助将不胜感激!

标签: django django-models django-rest-framework django-views django-rest-framework-simplejwt


【解决方案1】:

您试图在关系的多方面设置属性,但它不起作用。基本上,您只是在管理器上设置一个属性,而管理器就像任何其他表现良好的 python 对象一样,只会在其自身上设置此属性 - 但它没有做任何有用的事情。

相反,您应该 create() 一个新的 OTP 或 update() 一个特定的 OTP。

请记住,您的数据模型如下所示:

user:
   - otp1
   - otp2
   - otp3  

等等

因此没有“一个用户一个 OTP”。为此,您需要一个 OneToOneField。

【讨论】:

  • 谢谢!我最终将其转换为 OneToOneField 并使用了 update_or_create() 方法。
猜你喜欢
  • 2018-10-12
  • 2023-03-09
  • 1970-01-01
  • 2011-03-23
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 2018-02-06
  • 2019-11-06
相关资源
最近更新 更多