I am working on a Q&A application where I am using django-tastypie and jquery-ajax to create resources . I have two models or resouces , Question And Answer. Question has a foreignkey to TopicResouces and DifficultyLevelResource. and Answer has the foreignkey to question . everything is working fine when I am creating resources one by one. But now I am trying to create related objects as well as described in django-Tastypie. my resources code is
class QuestionResource(ModelResource):
topic = fields.ToOneField('courses.api.TopicResource','topic',null=True)
difficulty_level = fields.ForeignKey(DifficultyLevelResource, 'difficulty_level',null=True,full=True)
answers = fields.ToManyField('quiz.api.AnswerResource', 'answer_set', null=True, full=True)
class Meta:
queryset = Question.objects.all()
class AnswerResource(ModelResource):
question=fields.ForeignKey(QuestionResource,'question',null=True)
class Meta(CommonMeta):
queryset = Answer.objects.all()
resource_name = 'answer'
what I am posting is
curl -v -H "Content-Type: application/json" -X POST --data '{"explanation":"1+1+1+1=4","hint":"asadsa","question_text":"2+2","topic":"/api/v1/topic/2/","question_type": "NUM","difficulty_level":"/api/v1/difficultylevel/1/", "answers":[{"answer_text": "8","marks": "1.00"}]}' http://serverpath /api/vi/question/
but it always gives me a 404 error.
when I am sending the request from browser as
{"topic":"path to the related topic object ","question_text":"2+2","difficulty_level":"path to fficultylevel","question_type":"MCQ","explanation":"sssa","hint":"ssss","answers":[{"answer_text":"0","marks":"-0.25"},{"answer_text":"2","marks":"0.00"},{"answer_text":"3","marks":"-0.33"},{"answer_text":"None","marks":"1.00"}]}
It gives me traceback error
{"error_message": "", "traceback": "Traceback (most recent call last):\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/resources.py\",
line 202, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/resources.py\",
line 439, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/resources.py\",
line 471, in dispatch\n response = method(request, **kwargs)\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/resources.py\",
line 1313, in post_list\n updated_bundle = self.obj_create(bundle, **self.remove_api_resource_names(kwargs))\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/resources.py\",
line 2079, in obj_create\n return self.save(bundle)\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/resources.py\", line 2230,
in save\n m2m_bundle = self.hydrate_m2m(bundle)\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/resources.py\", line 930, in hydrate_m2m\n
bundle.data[field_name] = field_object.hydrate_m2m(bundle)\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/fields.py\",
line 853, in hydrate_m2m\n m2m_hydrated.append(self.build_related_resource(value, **kwargs))\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/fields.py\",
line 661, in build_related_resource\n return self.resource_from_data(self.fk_resource, value, **kwargs)\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/fields.py\",
line 620, in resource_from_data\n return fk_resource.full_hydrate(fk_bundle)\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/resources.py\", line 881, in full_hydrate\n
value = field_object.hydrate(bundle)\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/fields.py\", line 732, in hydrate\n value = super(ToOneField, self).hydrate(bundle)\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/tastypie/fields.py\",
line 165, in hydrate\n elif self.attribute and getattr(bundle.obj, self.attribute, None):\n\n File \"/home/learnomatics/hark-v0.1/local/lib/python2.7/site-packages/django/db/models/fields/related.py\", line 389, in __get__\n
raise self.field.rel.to.DoesNotExist\n\nDoesNotExist\n"
}
I have checkout many questions on stackoverflow and google groups but unable to understand the problem. tell me what I am doing is the right way to do it . help would be appreciated
I got the solution. The answer is here:
RelatedField.related_name
Used to help automatically populate reverse relations when creating data. Defaults to None.
In order for this option to work correctly, there must be a field on the other Resource with this as an attribute/instance_name. Usually this just means adding a reflecting ToOneField pointing back.
Example:
class EntryResource(ModelResource):
authors = fields.ToManyField('path.to.api.resources.AuthorResource', 'author_set', related_name='entry')
class Meta:
queryset = Entry.objects.all()
resource_name = 'entry'
class AuthorResource(ModelResource):
entry = fields.ToOneField(EntryResource, 'entry')
class Meta:
queryset = Author.objects.all()
resource_name = 'author'
Use of related_name does the task. it maps the objects of related fields and automatically populates the relations when creating data.