Reputation: 1779
I'm trying to add a comment model to another model on my site. Here's the Resource:
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()
Model:
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()
When trying to POST to this, it appears that tastypie isn't setting the question properly. (It might also be important that hydrate_FOO methods aren't being called for some reason.
Here's some sample data I sent:
{
"comment": "test",
"question": "/api/v1/question/1/"
}
Here's the error:
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
Upvotes: 0
Views: 235
Reputation: 71
As you point out, readonly
is a property to manage the attribute in the hydrate cycle. It doesn't really have anything to do with preventing the field from being editable in the next requests. If I understand correctly, you want to prevent the question
field to be edited in the future. You can do that either by deactivating modifications of the Resource, or by controlling those modifications.
If you want to prevent the Resource from being modified, just deactivate PUT
calls to the Comment resource by adding the next line to your Meta
:
allowed_methods = ['get', 'post',]
On the other hand, if you want to control how the PUT
behaves, you can control the hydrate and delete the new 'question' from the request, which will stop its modification:
def hydrate(self, bundle):
if bundle.request.method == 'PUT':
if 'question' in bundle.data:
bundle.data.pop('question',None)
return bundle
Upvotes: 1
Reputation: 1779
It turns out that tastypie doesn't even set readonly fields on the first POST. I guess this makes sense, but I still want fields that are only editable on initial POST.
Upvotes: 0