2013-08-29 142 views
0

我正在嘗試向我的網站上的其他模型添加評論模型。這裏的資源:使用ForeignKeys發佈模型會導致完整性錯誤

class CommentResource(ModelResource): 

    user = fields.ForeignKey(UserResource, 'user', readonly=True) 
    question = fields.ForeignKey(QuestionResource, 'question', readonly=True) 

    def hydrate_user(self, bundle): 
     return bundle.request.user 

    class Meta: 
     queryset = Comment.objects.all().order_by("-created") 
     resource_name = 'comment' 
     filtering = { 
      "session": ALL_WITH_RELATIONS, 
      "user": ALL_WITH_RELATIONS 
     } 
     authorization = CommentAuthorization() 

型號:

class Comment(models.Model): 

    question = models.ForeignKey(AMAQuestion, related_name = "comments") 
    user = models.ForeignKey(User, related_name = "comments") 

    created = models.DateTimeField(auto_now_add=True, editable=False) 
    edited = models.DateTimeField(auto_now=True, editable=False) 

    comment = models.TextField() 

當試圖張貼到這一點,似乎tastypie沒有正確設置的問題。 (這也可能是很重要的hydrate_FOO方法不會被調用由於某種原因

這是我送一些樣本數據:

{ 
    "comment": "test", 
    "question": "/api/v1/question/1/" 
} 

這裏的錯誤:

Traceback (most recent call last): 

    File "C:\Python33\lib\site-packages\django\db\backends\sqlite3\base.py", line 
362, in execute 
    return Database.Cursor.execute(self, query, params) 

sqlite3.IntegrityError: questions_comment.question_id may not be NULL 


During handling of the above exception, another exception occurred: 


Traceback (most recent call last): 

    File "C:\Python33\lib\site-packages\tastypie\resources.py", line 195, in wrapp 
er 
    response = callback(request, *args, **kwargs) 

    File "C:\Python33\lib\site-packages\tastypie\resources.py", line 426, in dispa 
tch_list 
    return self.dispatch('list', request, **kwargs) 

    File "C:\Python33\lib\site-packages\tastypie\resources.py", line 458, in dispa 
tch 
    response = method(request, **kwargs) 

    File "C:\Python33\lib\site-packages\tastypie\resources.py", line 1320, in post 
_list 
    updated_bundle = self.obj_create(bundle, **self.remove_api_resource_names(kw 
args)) 

    File "C:\Python33\lib\site-packages\tastypie\resources.py", line 2084, in obj_ 
create 
    return self.save(bundle) 

    File "C:\Python33\lib\site-packages\tastypie\resources.py", line 2230, in save 

    bundle.obj.save() 

    File "C:\Python33\lib\site-packages\django\db\models\base.py", line 546, in sa 
ve 
    force_update=force_update, update_fields=update_fields) 

    File "C:\Python33\lib\site-packages\django\db\models\base.py", line 650, in sa 
ve_base 
    result = manager._insert([self], fields=fields, return_id=update_pk, using=u 
sing, raw=raw) 

    File "C:\Python33\lib\site-packages\django\db\models\manager.py", line 215, in 
_insert 
    return insert_query(self.model, objs, fields, **kwargs) 

    File "C:\Python33\lib\site-packages\django\db\models\query.py", line 1675, in 
insert_query 
    return query.get_compiler(using=using).execute_sql(return_id) 

    File "C:\Python33\lib\site-packages\django\db\models\sql\compiler.py", line 93 
7, in execute_sql 
    cursor.execute(sql, params) 

    File "C:\Python33\lib\site-packages\django\db\backends\util.py", line 41, in e 
xecute 
    return self.cursor.execute(sql, params) 

    File "C:\Python33\lib\site-packages\django\db\backends\sqlite3\base.py", line 
364, in execute 
    six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys. 
exc_info()[2]) 

    File "C:\Python33\lib\site-packages\django\utils\six.py", line 328, in reraise 

    raise value.with_traceback(tb) 

    File "C:\Python33\lib\site-packages\django\db\backends\sqlite3\base.py", line 
362, in execute 
    return Database.Cursor.execute(self, query, params) 

django.db.utils.IntegrityError: questions_comment.question_id may not be NULL 

回答

1

正如您指出的那樣,readonly是管理水合物循環中屬性的屬性。這與防止下一次請求中的字段可編輯並無關係。如果我理解正確,那麼您想要防止將來編輯question字段。您可以通過停用對資源的修改或通過控制這些修改來做到這一點。

如果你想防止被修改的資源,僅僅通過增加下一行停用PUT呼叫註釋資源的Meta

allowed_methods = ['get', 'post',] 

在另一方面,如果你要控制PUT行爲,您可以控制水合物並從請求中刪除新的'問題',這將停止其修改:

def hydrate(self, bundle): 
    if bundle.request.method == 'PUT': 
     if 'question' in bundle.data: 
      bundle.data.pop('question',None) 
    return bundle 
+1

太棒了。我認爲我需要做這樣的事情,但對於我應該如何去做這件事有點困惑。這看起來很完美。另外,歡迎來到Stack Overflow。 = D –

+0

謝謝!樂意效勞 :) –

0

原來tastypie甚至不會在第一次POST時設置只讀字段,我想這是有道理的,但我仍然希望只能在初始POST中編輯的字段

相關問題