Django Tastypie: Imlementing Many To Many "through" relationships -
i have searched issue lot , gone through bunch of related questions on stack overflow, there doesn't seem definitive answer how implement many-to-many relationships "through" intermediate model (or maybe missed it).
i have model named sample has many-to-many relationship region. there intermediate model connects two, named sampleregion. not saving information on intermediate model, might in future.
here models:
class sample(models.model): sample_id = models.bigintegerfield(primary_key=true) description = models.textfield(blank=true) objects = models.geomanager() regions = manytomanyfield(region, through='sampleregion') class meta: db_table = u'samples' def save(self, **kwargs): # assign sample id create requests if self.sample_id none: try: id = sample.objects.latest('sample_id').sample_id + 1 except sample.doesnotexist: id = 1 self.sample_id = id super(sample, self).save class region(models.model): name = models.charfield(max_length=100, unique=true) def __unicode__(self): return self.name class meta: db_table = u'regions' class sampleregion(models.model): sample = models.foreignkey('sample') region = models.foreignkey(region) class meta: unique_together = (('sample', 'region'),) db_table = u'sample_regions'
and here 1 approach took write resources. it's not correct, , not able figure out right way of doing it:
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 = { 'version': all, 'sesar_number': } validation = versionvalidation(queryset, 'sample_id') def hydrate_regions(self, bundle): # code create new sampleregion object getting list of # regions bundle.data['regions'] class regionresource(modelresource): class meta: queryset = models.region.objects.all() allowed_methods = ['get'] resource_name = "region" filtering = { 'region': all, }
this how making post request:
post_data = { 'regions': ["/tastyapi/v1/region/2/"], 'description': 'created test case', } client.post('/tastyapi/v1/sample/', data = post_data, authentication = credentials, format = 'json')
this request doesn't work because bundle.data['regions'] none
time reaches hydrate_regions
.
does have advice on how should go implementing scenario?
i figured out couple of days ago. here's found...
django takes care of creating m2m relationships if not explicitly creating intermediate table. however, if explicitly using intermediate table, responsible creating record in intermediate table. working in tastypie, had override save_m2m
method explicitly create record in intermediate table linking sample have created , existing region.
this how relevant part of resources.py
looks 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): field_name, field_object in self.fields.items(): if not getattr(field_object, 'is_m2m', false): continue if not field_object.attribute: continue 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': }
Comments
Post a Comment