Khandelwal
Khandelwal

Reputation: 661

Updating related/nested resource (user/userprofile) - Seeing a duplicate key error on PATCH

I have a UserProfile class:

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    bio = models.CharField(max_length=180, null=True)

That is linked to the User class.

AUTH_PROFILE_MODULE = 'plantvillage.userprofile'

I'd like to provide one API through tastypie, so that user details and userprofile details can be managed at the same time. I would like to not expose two interfaces (one for user, and one for userprofiles) if possible.

I set up my resources like so:

class ProfileResource(ModelResource):
    class Meta:
        queryset = UserProfile.objects.all()
        resource_name = 'profile'
        authentication = ApiKeyAuthentication()
        authorization = DjangoAuthorization()
        allowed_methods = ['get', 'put', 'patch']

class UserResource(ModelResource):
    profile = fields.ToOneField(ProfileResource, 'userprofile', full=True)

    class Meta:
        queryset = User.objects.filter(is_staff=False)
        resource_name = 'usr'
        authentication = ApiKeyAuthentication()
        authorization = DjangoAuthorization()

        excludes = ['password', 'is_active', 'is_staff']

However, updating

curl --dump-header - -H "Authorization: ApiKey [email protected]:1432ece6a1f34fae24a77315b5c924f756f13807" -H "Content-Type: application/json" -X PATCH --data '{"profile":{"bio":"aquarium"}}' "http://127.0.0.1:8000/api/usr/25/"

Results in this error:

"error_message": "duplicate key value violates unique constraint \"plantvillage_userprofile_user_id_key\"\n", "traceback": "Traceback (most recent call last):\n\n  File \"/usr/local/lib/python2.6/dist-packages/django_tastypie-0.9.12_alpha-py2.6.egg/tastypie/resources.py\", line 196, in wrapper\n

What changes can I make to make this work?

Upvotes: 1

Views: 262

Answers (1)

kgr
kgr

Reputation: 9948

You can get rid of UserResource completely and add the fields from the User model you want to expose like this:

username = fields.CharField( attribute = 'user__username' )

This will not only send proper data from the User model in case of GET requests but also take care of the updates.

Upvotes: 2

Related Questions