【问题标题】:one to one field update serialization issue一对一字段更新序列化问题
【发布时间】:2021-02-17 16:12:34
【问题描述】:

######################要求######################## #####

/add_value/

有效载荷: { "profile_id": "34AB", “amt”:100.00 }

###################### 视图集######################## ############

class cash_viewset(ModelViewSet):

queryset = Cashbalance.objects.all()
serializer_class = SampleSerializer

#######################型号####################### ##############

型号-1 ---

类配置文件(models.Model):

user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_id = models.CharField(max_length=50,unique=True)

型号-2 ---

class Cashbalance(models.Model):

profile = models.OneToOneField(Profile, on_delete=models.CASCADE,db_column="profile_id")
remianingAmount = models.FloatField()
amt = models.FloatField()

##############################序列化程序############### ###############

类 SampleSerializer(serializers.ModelSerializer):

profile_id = serializers.CharField(source="profile.profile_id")
remianingAmount = serializers.FloatField(read_only=True)

class Meta:
    model = CashBalance
    fields = ["profile_id", "amt", "remianingAmount"]

def create(self, validated_data):
    profile_dict = validated_data['profile']
    userprofile = Profile.objects.get(profile_id=profile_dict['profile_id'])
    bank_obj = CashBalance.objects.filter(profile_id=userprofile)
    bank_obj.update(amt=validated_data['amt'], remianingAmount=validated_data['amt'])
    return bank_obj[0]

def to_representation(self, instance):
    data = super(serializers.ModelSerializer, self).to_representation(instance)
    print(instance.profile.user.username)
    result = {"profile_id": data['profile_id'], "name": instance.profile.user.username,
              "remianingAmount": data['remianingAmount']}
    return result

################################ 问题是############ ##########

假设,user、profile 和 Cashbalance 表中已经有一些数据

根据上面给出的有效载荷,基于 profile_id,我必须将 amt 值更新为 100,为此我已经在 create 方法中实现了解决方案(上面给出的创建方法),请分享您的输入,我希望无法在 create 方法中完成更新,如何使用 modelviewset 根据我的模型设计以更好的方式改进它

【问题讨论】:

    标签: django-rest-framework


    【解决方案1】:

    要执行更新,您必须覆盖序列化程序中的更新方法。

    def update(self, instance, validated_data):
      instance.profile.profile_id 
     = validated_data["profile"].get('profile_id',instance.profile.profile_id)
      instance.amt = validated_data.get('amt', instance.amt) 
      return instance
    

    在你的视图中

    def update(self,request,pk=None):
       profile_id = request.data.get("profile_id")
       profile = Profile.objects.get(profile_id = profile_id)
       ser = self.get_serializer_class()(instance=profile.cash_balance , data = request.data)
       ser.is_valid(raise_exception=True)
       ser.save()
    

    在您的 CashBalanceModel 中,传递一个 related_name

    profile = models.OneToOneField(Profile, on_delete=models.CASCADE,db_column="profile_id" , related_name="cash_balance")
    

    查看文档:https://www.django-rest-framework.org/api-guide/serializers/

    【讨论】:

    • 感谢您的回复,错误在第一行给出 - AttributeError: 'ForwardOneToOneDescriptor' 对象没有属性 'profile_id' 当我检查它显示为模型库的实例类型并且如果我打印“ instance" 如果我​​执行 print(instance.profile.profile_id),它将作为 给出 - 与第一行相同的错误
    • 当我使用端点 url 作为“/add_value/{pk}”时,这种方法很好只是想了解,我要求使用端点作为“/add_value/”并且上面也给出了有效负载,所以我相信这种方法不适合要求,请建议如何通过获取有效负载以其他方式更新表
    • 如果想这样做,您还需要覆盖视图集中的更新方法。我已经更新了答案。
    • 是的,它工作正常,非常感谢您对此提供的帮助。在本地机器中执行时,在视图集中,应该存在创建方法而不是更新和返回响应对象,然后它的工作完美还有序列化器中的 instance.save() ,然后完美更新,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多