I figured this out a couple of days ago. Here's what I found...
Django takes care of creating M2M relationships for you if you are not explicitly creating an intermediate table. However, if you are explicitly using an intermediate table, then you are responsible for creating a record in the intermediate table. To get this working in Tastypie, I had to override the save_m2m
method to explicitly create a record in the intermediate table linking my the sample I have just created and an existing region.
This is how the relevant part of my resources.py
looks like now:
class SampleResource(ModelResource):
regions = fields.ToManyField("tastyapi.resources.RegionResource",
"regions")
class Meta:
queryset = models.Sample.objects.all()
allowed_methods = ['get', 'post', 'put', 'delete']
authentication = ApiKeyAuthentication()
authorization = ObjectAuthorization('tastyapi', 'sample')
excludes = ['user', 'collector']
filtering = {
'regions': ALL_WITH_RELATIONS,
}
validation = VersionValidation(queryset, 'sample_id')
def save_m2m(self, bundle):
for field_name, field_object in self.fields.items():
if not getattr(field_object, 'is_m2m', False):
continue
if not field_object.attribute:
continue
for field in bundle.data[field_name]:
kwargs = {'sample': models.Sample.objects.get(pk=bundle.obj.sample_id),
'region': field.obj}
try: SampleRegion.objects.get_or_create(**kwargs)
except IntegrityError: continue
class RegionResource(BaseResource):
class Meta:
queryset = models.Region.objects.all()
authentication = ApiKeyAuthentication()
allowed_methods = ['get']
resource_name = "region"
filtering = { 'region': ALL }