Conduit lets you use other ModelResources for your related object fields. You can use a related resource by referencing it in the Fields metaclass. The below FooResource example using two related resource fields:
Using a related resource lets you embed the entire resource data inside of the parent resource. One of the resources above is set to embed=True, while the other is not and will default to the resource_uri
. An example of the above FooResource would look like this:
{
"bar": "/api/v1/bar/23/",
"name": "stuffs",
"id": 1,
"bazzes": [
{
"resource_uri": "/api/v1/baz/1/",
"id": 1,
"name": "Baz 1"
},
{
"resource_uri": "/api/v1/baz/7/",
"id": 7,
"name": "Baz 7"
}
],
"resource_uri": "/api/v1/foo/1/"
}
GenericForeignKeyField
When a model should relate to multiple types of models, Django provides the GenericForeignKey field and ContentTypes framework, allowing a model to relate to multiple models based on a ContentType and Id.
If a model is using Django’s GenericForeignKey
, the GenericForeignKeyField
provided by Conduit can be used to setup a resource.
Here’s an example of a model using a GenericForeignKey:
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.db import models
class Item(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericFreignKey('content_object', 'object_id')
A ModelResource
using Conduit’s GenericForeignKeyField
would look like this:
from conduit.api import ModelResource
from conduit.api.fields import GenericForeignKeyField
from myapp.models import Item
class ItemResource(ModelResource):
class Meta(ModelResource.Meta):
model = Item
class Fields:
content_object = GenericForeignKeyField(
attribute='content_object',
resource_map={
'Bar': 'api.views.BarResource',
'Foo': 'api.views.FooResource',
}
)
The resource_map
attribute enables the resource to lookup a related resource based on it’s Model
defined by the ContentType. In this example we use the Foo and Bar models and resources explained above.
Here is an example of what the api would return for a GET request:
{
"object_id": 1,
"content_object": "/api/v1/bar/1/",
"id": 1,
"content_type": 8,
"resource_uri": "/api/v1/item/1/"
}
If embed=True
is set, then the full related resource will be included using the same behavior for a ForeignKeyField
or ManyToManyField
.