Django TastyPie ToManyField relation complains "has no data and doesn't allow a null value" on POST of new item

StackOverflow https://stackoverflow.com/questions/22575585

  •  19-06-2023
  •  | 
  •  

Question

In my application, I've got "comments" (actually not quite, but a simple way to think about it), and other users can vote on comments (currently, it's just a simple model, with a user adding just a +1, or removing it, just like a Facebook 'like' or a Google Plus +1).

My Django model looks like this (in the relevant part).

class CommentaryEntry(models.Model):
    commentary = models.TextField(null=False)
    section = models.ForeignKey(Section)
    user = models.ForeignKey(User)
    creation_date = models.DateTimeField(default=now)
    votes = models.IntegerField(default=0)
    class Meta:
            ordering = ['-votes', 'creation_date']

class CommentaryEntryVoter(models.Model):
    entry = models.ForeignKey(CommentaryEntry)
    voter = models.ForeignKey(User)
    vote_date = models.DateTimeField(default=now)
    class Meta:
            unique_together = ('entry', 'voter')

The "votes" field in CommentaryEntry is a simple incremented integer which will probably be replaced by a simple count of the CommentaryEntryVoters in a future iteration (i.e. as soon as I fix this problem).

Both of these objects are created and destroyed with a TastyPie API.

In my tasty pie apis.py the resources look like this;

class CommentaryEntryResource(ModelResource):
    section = fields.ForeignKey(SectionResource, 'section', related_name='user_commentaries')
    user = fields.ForeignKey(UserResource, 'user')
    voters = fields.ToManyField(CommentaryEntryVoterResource, 'commentaryentryvoter_set', related_name='entry')

    class Meta:
            queryset = CommentaryEntry.objects.all()
            resource_name = 'sourcecommentary'
            list_allowed_methods = ['get', 'put', 'post', 'delete']
            authentication = SessionAuthentication()
            authorization = UpdateUserObjectsOnlyAuthorization()
            filtering = {
                    'section': ALL_WITH_RELATIONS,
                    'user': ALL_WITH_RELATIONS,
                    'voters': ALL_WITH_RELATIONS,
            }

class CommentaryEntryVoterResource(ModelResource):
    voter = fields.ForeignKey('decommentariis.api.UserResource', 'voter')
    entry = fields.ForeignKey(CommentaryEntryResource, 'entry', related_name='voters')
    class Meta:
            queryset = CommentaryEntryVoter.objects.all()
            resource_name = "voterhistory"
            list_allowed_methods = ['get', 'post', 'delete']
            authentication = SessionAuthentication()
            authorization = UpdateUserObjectsOnlyAuthorization()
            filtering = {
                    'entry': ALL_WITH_RELATIONS,
                    'voter': ALL_WITH_RELATIONS,
            }

When I try to POST a new CommentaryEntryResource, Tasty Pie returns a HTTP error 400 'bad request' with the responseText: "The 'voters' field has no data and doesn't allow a null value" ... But, it should be null. This is a new comment and doesn't have any voters yet. I'm not setting the value in the JSON payload that's sent up to the server.

However, if I reload, then I can see that the CommentaryEntry was actually created, and with no voters, but this might be because on my test instance I'm only using sqlite DB and there's no transaction to roll back.

How do I allow that? In fact I want to enforce it - new comments clearly can't have any voters.

Python 3.3, Django 1.6.2, TastyPie 0.11.0

Update: if I add the empty list to the payload in my Javascript;

var data = JSON.stringify({
  "commentary": commentarytext,
  /* omitted for brevity */
  "voters": [],
});

Then it posts OK. But I would still like to discover how to allow/enforce a null list to begin with.

Was it helpful?

Solution

Use the atribute null = True for your your voters fields. Thanks!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top