Search code examples
djangodjango-modelstastypie

How to create records when a model has one-to-many self referential relationship using TastyPie?


I am making POST requests using TastyPie. The Task model has a one-to-many self referential relationship via the parent_task_id field.

Model:

class Task(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    parent_task_id = models.ForeignKey(
            "self",
            on_delete=models.CASCADE,
            null=True, blank=True)

In my api.py

class TaskResource(ModelResource):
    parent_task_id_id = fields.ToOneField('self', 'id', null=True, full=True)

    class Meta:
        queryset = Task.objects.all()
        authorization = Authorization()
        allowed_methods = ['post']
        resource_name = "create_task"

I am unable to create a Task when I specify the parent_task_id using Postman.

{
    "title": "ABCDERT",
    "description": "world this week",
    "due_date": "2018-11-12 1:2:1",
    "parent_task_id_id": "2"
}

This is the error message I am getting when I do that:

  "error_message": "An incorrect URL was provided '2' for the 'CreateTaskResource' resource.",

Solution

  • You should specify parent_task's uri rather than id, like

    { "title": "ABCDERT", "description": "world this week", "due_date": "2018-11-12 1:2:1", "parent_task_id_id": "/create_task/2" }

    In addition, it is incorrect to define the foreignkey field in resource in this way,

    class TaskResource(ModelResource): parent_task_id_id = fields.ToOneField('self', 'id', null=True, full=True) you can see the docs for detail.

    I adjust your example,like: model:

    class Task(models.Model):
        title = models.CharField(max_length=100)
        description = models.TextField()
        parent_task = models.ForeignKey("self", on_delete=models.CASCADE, null=True, blank=True)
    

    api.py

    class TaskResource(ModelResource):
        parent_task = fields.ToOneField('self', 'parent_task', null=True,
            full=True)
        class Meta:
            queryset = Task.objects.all()
            authorization = Authorization()
            allowed_methods = ['post', 'get']
            filtering = {'id': ALL, 'parent_task': ALL_WITH_RELATIONS}
            resource_name = "task"
    
    1. Create task

    POST body like:

    { "title": "task2", "description": "world this week", "due_date": "2018-11-12 1:2:1", "parent_task":"/api/v1/task/1/" }

    1. foreignkey query

    GET parameter like:

    0.0.0.0:8000/api/v1/task/?parent_task__id=1