Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django tastypie: Resource show different in detailed request as in list request

I Am just starting with django tastypie, and I Am enthousiastic about it. My question: I Am searching for the same feature as in the admin view: specify for foreignkey fields what to see in the list response of other objects and what in the detailed response.

let's say this is my simplyfied model:

class Location(models.Model):
    name = models.CharField(max_length=256, blank=True)
    longitude = models.FloatField(blank=True, default=0.0)
    latitude = models.FloatField(blank=True, default=0.0)
    description = models.CharField(max_length=256, blank=True)
    shortname = models.CharField(max_length=256, blank=True)
    tooltiptext = models.CharField(max_length=1000, blank=True)
    locationtype = models.ForeignKey(LocationType, blank=True, null=True)
    public_anonymous = models.BooleanField(default=False, blank=False, null=False)
    public_authorized = models.BooleanField(default=False, blank=False, null=False)
    def __str__(self):
        return '%s' % (self.name)

class Variable(models.Model):
    abbreviation = models.CharField(max_length=64, unique=True)    
    name = models.CharField(max_length=256, blank=True)
    unit = models.CharField(max_length=64, blank=True)
    def __str__(self):
        return '%s  [%s]' % (self.name, self.unit)

class Timeseries(models.Model):
    locationkey = models.ForeignKey(Location)
    variablekey = models.ForeignKey(Variable)
    tstypekey = models.ForeignKey(TimeseriesType)

    def __str__(self):
        return '%s: %s (%s)' % (self.locationkey.name, self.variablekey.name, self.tstypekey.name)

and these are my resources for the api:

class LocationResource(ModelResource):
    class Meta:
        queryset = Location.objects.all()
        resource_name = 'location'
        excludes = ['public_anonymous', 'public_authorized']
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

class VariableResource(ModelResource):
    class Meta:
        queryset = Variable.objects.all()
        resource_name = 'variable'
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

class TimeseriesTypeResource(ModelResource):
    class Meta:
        queryset = TimeseriesType.objects.all()
        resource_name = 'timeseriestype'
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

class TimeseriesResource(ModelResource):
    location = fields.ForeignKey(LocationResource, 'locationkey', full=False) 
    variable = fields.ForeignKey(VariableResource, 'variablekey', full=False) 
    timeseriestype = fields.ForeignKey(TimeseriesTypeResource, 'tstypekey', full=False) 

    class Meta:
        queryset = Timeseries.objects.all()
        resource_name = 'timeseries'
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

In the TimeseriesResource if you use full=False, you just get an url with an id, if you use full=True you get all the information. In real the location has a lot more information. I need just a bit more information than full='False' but not all the information using full=True. I do not want to use the exclude option, because than I do not have the information in the detailed information or in the list of the Location object itselve.

one of the options I was thinking about, is making 2 resources for the same object, but this doesn't feel like the best solution (but I guess it will work). By the way: I thought over this option, will not work (ofcourse), better use the workaround usggested in the answer of bmihelac (thanks).

Although... trying the workaround... leads me to a new question, see:

django-tastypie: Cannot access bundle.request in dehydrate(self,bundle)

like image 241
michel.iamit Avatar asked Nov 23 '11 13:11

michel.iamit


2 Answers

There is a feature request for different fields in show and index, alnong with some discussion how it could be implemented:

https://github.com/toastdriven/django-tastypie/issues/18

Until this feature is not included, maybe you can help with this workaround:

https://github.com/toastdriven/django-tastypie/issues/18#issuecomment-2695447

like image 135
bmihelac Avatar answered Nov 01 '22 22:11

bmihelac


Good news! This has been added to tastypie.

If you wish to set up a field to be only on certain pages, simply define the use_in attribute to be either 'all', 'list' or 'detail'.

More info here, but I'll provide an example for posterity:

class DocumentResource(ModelResource):
    my_field = fields.CharField(attribute='my_field', use_in='detail')

Simple as that!

like image 5
mlissner Avatar answered Nov 01 '22 22:11

mlissner