On my post method I'd like to automatically populate the 'owner' field with the current user (I'm using BasicAuthentication). I followed some of the code here: How to get authorized user object in django-tastypie - but I've not quite got it working right yet.
resources.py:
class QuestionResource(ModelResource):
owner = fields.ForeignKey(UserResource, 'owner')
class Meta:
queryset = Question.objects.all()
allowed_methods = ['get','post']
fields = ['title','type']
resource_name = 'question'
include_resource_uri = True
serializer = PrettyJSONSerializer()
authentication = BasicAuthentication()
authorization = Authorization()
def obj_create(self, bundle, request=None, **kwargs):
bundle = self.full_hydrate(bundle, request)
return bundle
def obj_update(self, bundle, request=None, **kwargs):
bundle = self.full_hydrate(bundle, request)
return bundle
def full_hydrate(self, bundle, request=None):
bundle = self.hydrate(bundle, request)
return bundle
def hydrate(self, bundle, request=None):
bundle.obj.owner = User.objects.get(pk = request.user.id)
return bundle
If I issue the following:
curl -u USERNAME:XXXXXXX --dump-header - -H "Accept: application/json" -H "Content-Type: application/json" -X POST --data "{\"title\":\"my new question\",\"type\":\"multichoice\"}" http://localhost/python/mquiz/api/v1/question/
I get the response:
HTTP/1.1 201 CREATED
Date: Fri, 02 Nov 2012 08:28:05 GMT
Server: Apache/2.2.22 (Ubuntu)
Vary: Accept-Language,Cookie,Accept-Encoding
Location: http://localhost/python/mquiz/api/v1/question/None/
Content-Language: en-us
Content-Length: 0
Content-Type: text/html; charset=utf-8
So it appears as if it has all worked, but there's nothing added to the database, and the Location looks wrong (with the /None/ at the end).
I'm sure it's something to do with the line "bundle.obj.owner = User.objects.get(pk = request.user.id)". If I use "bundle.obj.owner = request.user.id" then I get the error:
"error_message": "Cannot assign \"3L\": \"Question.owner\" must be a \"User\" instance."
As far as I can tell the bundle.obj.owner needs to be in the form: '/python/mquiz/api/v1/user/3/' - if I use this as the owner param in the data in my curl request (and remove my custom hydrate method), then it all works fine and gets added to the database. So how can I transform my User instance into the form that will be accepted?
Any help much appreciated.
The current validated answer is sub-optimal since it results in 2 SQL queries.
You should rather modify your queryset as follow:
queryset = Question.objects.select_related('owner').all()
This way the 'owner' data is joined in one single SQL query.