Django TastyPie ToManyField 关系在添加新项时抱怨“没有数据且不允许空值”

1 投票
1 回答
1062 浏览
提问于 2025-04-17 23:24

在我的应用程序中,有一个“评论”功能(其实不完全是这样,但这样理解比较简单),其他用户可以对评论进行投票(目前,这只是一个简单的模型,用户可以添加一个 +1,或者取消,就像 Facebook 的“赞”或 Google Plus 的 +1 一样)。

我的 Django 模型大致是这样的(相关部分)。

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')

在 CommentaryEntry 中,“votes”字段是一个简单的递增整数,未来可能会被 CommentaryEntryVoters 的简单计数所替代(也就是说,一旦我解决了这个问题,就会这样做)。

这两个对象都是通过 TastyPie API 创建和销毁的。

在我的 tasty pie apis.py 中,资源看起来是这样的;

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,
            }

当我尝试发布一个新的 CommentaryEntryResource 时,Tasty Pie 返回一个 HTTP 错误 400 '错误请求',并且响应文本是:“'voters' 字段没有数据,并且不允许为空值”……但它应该是空的。这是一个新的评论,还没有任何投票者。我没有在发送到服务器的 JSON 数据中设置这个值。

不过,如果我刷新页面,就能看到 CommentaryEntry 实际上是被创建了,并且没有投票者,但这可能是因为我在测试实例中只使用了 sqlite 数据库,没有事务可以回滚。

我该如何允许这种情况呢?实际上,我想强制执行这一点——新的评论显然不能有任何投票者。

使用的技术是 Python 3.3,Django 1.6.2,TastyPie 0.11.0

更新:如果我在我的 JavaScript 中向数据负载添加一个空列表;

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

那么它就能正常发布。但我仍然想知道如何一开始就允许/强制使用一个空列表。

1 个回答

1

在你的 voters 字段中使用 null = True 这个属性。谢谢!

撰写回答