Reputation: 5221
I can't figure out how to create new related object when I update my User instance. Here'are my models:
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)
Here are my serializers:
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',)
Here's the actual view:
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)
I need to create new Weight object every time I update User info. How can I do that? When I'm trying to do it now, I get AttributeError: can't set attribute
.
Upvotes: 0
Views: 129
Reputation: 41671
In Django REST Framework 3.0, serializers must explicitly handle nested updates, which is essentially what you are trying to do here. You would just need to override perform_update
and have it create the new Weight
object instead of manually updating it.
In Django REST Framework 2.4, much of this happens automagically, and you are trying to change that magic behavior.
Django will do an update on a model object if the object has an id
on it, and an update if id
is set to None
. This means that you can create a basic copy of the object by setting the id
to None
, which is the easiest way to do what you are looking for right now.
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)
This should cause a new Weight
object to be created each time the user is updated.
Upvotes: 1