Search code examples
ajaxdjangoposttastypie

Django Tastypie posting with ForeignKey


I am currently learning Django and Tastypie. I have looked all over for an answer, but can't seem to find anything that addresses this issue specifically.

I have defined three resources in Tastypie: User, Search and Comment. There are many comments for a search.

A simplified look at models.py are:

class Search(models.Model):
    search_name = models.CharField(max_length=40, unique=True)
    search_slug = models.SlugField(default='')
    search_description = models.TextField(blank=True)
    splunk_search = models.TextField()
    splunk_results = models.TextField(blank=True)

class Comment(models.Model):
    search = models.ForeignKey(Search)
    author = models.ForeignKey(User)
    comment_title = models.CharField(max_length=80)
    comment = models.TextField()

And in my api.py:

class UserResource(ModelResource):
    class Meta:
        queryset = User.objects.all()
        resource_name = 'user'

class SearchResource(ModelResource):
    comments = fields.ToManyField('myapp.api.CommentResource','comments', null=True, blank=True)

    class Meta:
        queryset = Search.objects.all()
        list_allowed_methods = ['get', 'post']
        detail_allowed_methods = ['get', 'post', 'put', 'delete']
        resource_name = 'search'
        serializer = urlencodeSerializer()
        authentication = Authentication()
        authorization = Authorization()

class CommentResource(ModelResource):
    search = fields.ToOneField(SearchResource, 'search')

    class Meta:
        queryset = Comment.objects.all()
        resource_name = 'comment'
        list_allowed_methods = ['get', 'post']
        detail_allowed_methods = ['get', 'post', 'put', 'delete']
        authorization = Authorization()
        authentication = Authentication()
        serializer = urlencodeSerializer()
        validation = FormValidation(form_class=CommentForm)

My submit handler in js:

 $.ajax({
     type: 'POST',
     url: '/api/v1/comment/',
     dataType: 'json',
     data: $("#commentForm").serialize(),
     processData: false,
     success: function(messages) {
     console.log("Success!");
   },
   error: function() {
     console.log("Oh no, something went wrong!");
   }
 });

I always get back the response: Comment has no search.

Also, this form works perfectly fine outside of tastypie. The original django form has excluded both the search and the author fields and their data is pre-populated. I just can't seem to make the same thing work in Tastypie. Thank you in advance for any advice.


Solution

  • You made SearchResource to have comments (m2m relation) but you didn't specify it in model class Search, so I suppose you used reverse relationship.

    If so, instead of,

    class SearchResource(ModelResource):
        comments = fields.ToManyField('myapp.api.CommentResource','comments', null=True, blank=True)
    

    change to,

    class SearchResource(ModelResource):
        comments = fields.ToManyField('myapp.api.CommentResource', 'comment_set', related_name='search', null=True, full=True)
    

    The problem "comment has no search" because you didn't specify related_name. In another side, class Search has no attribute comments but comment_set (reverse relationship).