更新一个时创建新的相关对象

时间:2014-12-13 09:43:33

标签: python django django-rest-framework

当我更新User实例时,我无法弄清楚如何创建新的相关对象。这是我的模特:

class User(AbstractBaseUser, PermissionsMixin):
    name = models.CharField(max_length=50, verbose_name=_('Name'))
    email = models.EmailField(max_length=50, unique=True, verbose_name=_('Email'))

class Weight(models.Model):
    value = models.FloatField()
    units = models.IntegerField(choices=UNITS)
    created = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(User)

以下是我的序列化程序:

class UserSerializer(serializers.ModelSerializer):
    weight = WeightSerializer(source='weight')

    class Meta:
        model = User
        fields = ('name', 'email', 'weight')

class WeightSerializer(serializers.ModelSerializer):
    class Meta:
        model = Weight
        fields = ('value', 'units',)

以下是实际观点:

class UserDetails(APIView):
    def post(self, request, format=None):
        user = request.user
        if user.is_authenticated():
            serializer = UserSerializer(user, data=request.DATA, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data)

每次更新用户信息时,我都需要创建新的Weight对象。我怎样才能做到这一点?当我现在尝试这样做时,我得到AttributeError: can't set attribute

1 个答案:

答案 0 :(得分:1)

在Django REST Framework 3.0 中,序列化程序必须显式处理嵌套更新,这基本上就是您在此处尝试执行的操作。您只需要覆盖perform_update并让它创建新的Weight对象,而不是手动更新它。

在Django REST Framework 2.4 中,大部分都是自动,并且您正试图改变这种神奇的行为。

如果对象上有id,Django会对模型对象进行更新,如果id设置为None,则会更新。这意味着您可以通过将id设置为None来创建对象的基本副本,这是您现在正在寻找的最简单方法。

class UserDetails(APIView):
    def post(self, request, format=None):
        user = request.user
        if user.is_authenticated():
            serializer = UserSerializer(user, data=request.DATA, partial=True)
            if serializer.is_valid():
                user.weight.pk = None
                user.weight.save()
                serializer.save()
                return Response(serializer.data)

这会导致每次更新用户时都会创建一个新的Weight对象。