Django TastyPie deletes children if adding other

2019-08-22 03:53发布

问题:

I have one parent resource which can have more than one children of one attrbiute and one than more children of other attribute. They look like this:

class RouteResource(ModelResource):
    creator = fields.ForeignKey(UserProfileResource, 'creator', full=True)
    towns = fields.ToManyField(TownResource, 'towns', full=True, null=True)

model is:

class Route(models.Model):
    name = models.CharField(max_length=50)
    description = models.CharField(max_length=500)
    average_rate = models.FloatField(null=True, blank=True, default=0)
    date_created = models.DateTimeField(auto_now=True, auto_now_add=True)

    creator = models.ForeignKey(UserProfile)
    towns = models.ManyToManyField(Town)

    def __unicode__(self):
        return self.name

second resource is:

class MarkerResource(MultipartResource, ModelResource):
    route = fields.ForeignKey(RouteResource, 'route')
    picture = fields.FileField(attribute="picture", null=True, blank=True)

and it's model is:

class Marker(models.Model):
    picture = models.FileField(upload_to=get_upload_file_name, null=True, blank=True, max_length=500)
    description = models.CharField(max_length=500)

    longitude = models.FloatField()
    latitude = models.FloatField()

    order = models.IntegerField()

    route = models.ForeignKey(Route)

OK, now, I can successfuly add route with towns and my resource looks good:

{
. . .
. . .
"towns": [
    {
        "id": 1,
        "name": "my town",
        "resource_uri": "/api/v1/town/1/"
    }
]
}

Now I would like to add one marker which has predefined route as foreign key by doing POST:

    {
        "description": "Center of earth",
        "latitude": 0,
        "longitude": 0,
        "order": 1,
        "picture": null,
      "route": {
        "id":59
      }
    }

after that my marker is successfully added to correct Route, but towns which I've added with route get removed so my route doesn't have any towns:

{
    "towns": []
}

回答1:

You can either:

  • provide full resource uri for the key's value, i.e: route: "/api/v1/route/59/"
  • override the hydrate_route method of the MarkerResource to return an object given dictionary passed.
  • create a custom field based off fields.ForeignKey that would implement custom build_related_resource behaviour.