【问题标题】:django : Update two models using same API calldjango:使用相同的 API 调用更新两个模型
【发布时间】:2019-11-03 04:22:06
【问题描述】:

我有一个获取和接收用户数据的 API 调用, 用户模型看起来像这样 -

我有一个用户模型 -

{
    "id": 23,
    "name": "fname",
    "height": null,
    "weight": "59",
    "blood_pressure": "131",
    "blood_sugar": "320",
    "email": "m@gmail.com",
}

我想保存这些数据以保存在UserBody模型中-

"height": null,
"weight": "59",
"blood_pressure": "131",
"blood_sugar": "320",

虽然我希望将其余数据(id、姓名、电子邮件)保存在 BodyModel

我的User 模型看起来像这样 -

class MyUser(AbstractBaseUser, PermissionMixin):
    name = models.CharField(max_length=63, blank=True)
    height = models.IntegerField(blank=false, null=false)
    weight = models.IntegerField(blank=true, null=false)
    blood_pressure = models.IntegerField(blank=true, null=false)
    blood_sugar = models.IntegerField(blank=true, null=false)
    email = models.CharField(max_length=63, blank=True)

班级UserBody -

class UserBody(AbstractBaseUser, PermissionMixin):
        user = models.OneToOneField(MyUser, on_delete=models.CASCADE)
        height = models.IntegerField(blank=false, null=false)
        weight = models.IntegerField(blank=true, null=false)
        blood_pressure = models.IntegerField(blank=true, null=false)
        blood_sugar = models.IntegerField(blank=true, null=false)

我摆弄了user 对象foreignKey,但我无法理解它应该如何工作。我有一个MyUser 序列化程序,但我只是不知道如何为UserBody 模型编写序列化程序。 任何方向帮助我,我会从那里继续前进。

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    首先,您不应该从 AbstractBaseUser 继承您的两个模型以防止数据重复(在这种情况下,两个模型将具有相同的字段,例如“密码”、“组”等)。此外,出于相同的原因,您不应在两个模型中定义相同的字段,例如“身高”、“体重”等——这不是 DRY 方法。相反,您需要从 AbstractBaseUser 继承 User 模型,从 models.Model 继承 UserBody。类似的东西:

    class User(AbstractUser):
        name = models.CharField(max_length=63, blank=True)
        email = models.CharField(max_length=63, blank=True)
    
        def __str__(self):
            return self.username
    
    
    class UserBody(models.Model):
        user = models.OneToOneField(User, related_name='user_bodies', on_delete=models.CASCADE)
        height = models.IntegerField(blank=False, null=False)
        weight = models.IntegerField(blank=True, null=False)
        blood_pressure = models.IntegerField(blank=True, null=False)
        blood_sugar = models.IntegerField(blank=True, null=False)
    

    序列化器:

    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            exclude = ('groups', 'user_permissions', )
    
    
    class UserBodySerializer(serializers.ModelSerializer):
        user = UserSerializer(required=True)
    
        def create(self, validated_data):
            user_data = validated_data.pop('user')
            user = UserSerializer.create(UserSerializer(), validated_data=user_data)
            user_body, created = UserBody.objects.update_or_create(user=user, **validated_data)
    
        class Meta:
            model = UserBody
            fields = '__all__'
    

    查看:

    class UserBodyView(APIView):
        permission_classes = (AllowAny, )
    
        def get(self):
            user_bodies = UserBody.objects.all()
            serializer = UserBodySerializer(user_bodies, many=True)
            return Response(serializer.data)
    
        def post(self, request):
            serializer = UserBodySerializer(data=request.data)
            if serializer.is_valid(raise_exception=ValueError):
                serializer.create(validated_data=request.data)
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.error_messages,
                            status=status.HTTP_400_BAD_REQUEST)
    

    添加到 urlpatterns:

    path('api/v1/bodies/', UserBodyView.as_view(), name='user-bodies')

    现在您有以下端点: /api/v1/bodies/

    如果您发布以下数据:

    {
            "height": 170,
            "weight": 70,
            "blood_pressure": 120,
            "blood_sugar": 20,
            "user": {
                "username": "dimitrionian",
                "email": "john_doe@gmail.com",
                "password": "qweqwe123"
        }
    }
    

    它将创建一个用户实例和链接的 user_body 实例。序列化程序将返回以下内容:

    {
      "user": {
        "password": "qweqwe123",
        "last_login": null,
        "username": "dimitrionian",
        "email": "john_doe@gmail.com"
      },
      "height": 170,
      "weight": 70,
      "blood_pressure": 120,
      "blood_sugar": 20
    } 
    

    这是一个有效且经过测试的案例。您可以根据自己的需要进一步完善它。例如,设置所需的权限而不是应用 AllowAny

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-29
      • 1970-01-01
      • 2018-12-25
      • 1970-01-01
      • 1970-01-01
      • 2010-12-28
      相关资源
      最近更新 更多