Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating related resources with Tastypie

I would like tastypie to create a UserProfileResource as a result of me POSTing to a UserResource.

models.py:

class UserProfile(models.Model):
    home_address = models.TextField()
    user = models.ForeignKey(User, unique=True)

resources.py

class UserProfileResource(ModelResource):
    home_address = fields.CharField(attribute='home_address')

    class Meta:
        queryset = UserProfile.objects.all()
        resource_name = 'profile'
        excludes = ['id']
        include_resource_uri = False


class UserResource(ModelResource):
    profile = fields.ToOneField(UserProfileResource, 'profile', full=True)
    class Meta:
        queryset = User.objects.all()
        resource_name = 'user'
        allowed_methods = ['get', 'post', 'delete', 'put']
        fields = ['username']
        filtering = {
                'username': ALL,
                }

curl command:

curl -v -H "Content-Type: application/json" -X POST --data '{"username":"me", "password":"blahblah", "profile":{"home_address":"somewhere"}}' http://127.0.0.1:8000/api/user/

But I am getting:

 Django Version:   1.4
 Exception Type:   IntegrityError
 Exception Value:
 null value in column "user_id" violates not-null constraint

It seems like a chicken and egg scenario. I need the user_id to create the UserProfileResource and I need the profile to create the UserResource. Obviously I am doing something very silly.

Can anyone out there shine a light? Many thanks johnoc

I modified my code as Pablo suggested below.

class UserProfileResource(StssRessource):
    home_address = fields.CharField(attribute='home_address')
    user = fields.ToOneField('resources.UserResource', attribute='user', related_name='profile')

    class Meta:
        queryset = UserProfile.objects.all()
        resource_name = 'profile'


class UserResource(ModelResource):
    profile = fields.ToOneField('resources.UserProfileResource', attribute='profile', related_name = 'user', full=True)
    class Meta:
        queryset = User.objects.all()
        resource_name = 'user'

But am getting :

 Django Version:   1.4
 Exception Type:   DoesNotExist

Which relates to trying to access the User resource in the ORM and it not existing while its creating the related_objects UserProfileResource. Which is correct. The User ORM isnt created until after the related_objects have been created.

Anyone else seen this??

like image 628
johnoc Avatar asked May 14 '12 11:05

johnoc


1 Answers

After 2 days I finally managed to save related resources, the problem was that you have to specify both sides of the relation and their related names, in your case it would be something like that:

class UserProfileResource(ModelResource):
    home_address = fields.CharField(attribute='home_address')
    user = fields.ToOneField('path.to.api.UserResource', attribute='user', related_name='profile')
         #in my case it was a toManyField, I don't know if toOneField works here, you can try toManyField.

class UserResource(ModelResource):
    profile = fields.ToOneField(UserProfileResource, 'profile', related_name='user', full=True)
like image 59
Pablo Avatar answered Oct 01 '22 20:10

Pablo