Control of fields on nested models

53 views
Skip to first unread message

Malcolm Box

unread,
Oct 25, 2010, 9:03:21 AM10/25/10
to django-piston
Hi,

I'm just getting started with piston and am running into some problems
with controlling what fields show up in different APIs. I'm not sure
whether this is a genuine limitation, or a misunderstanding on how
this is supposed to work, so any advice or help would be welcome.

Here's the situation: I have a model (call it Poll) with a bunch of
fields, and a handler (PollHandler) that provides an API to it. I
have another handler that provides an API to a Carousel
(CarouselHandler) which includes Slides that each have a Poll. For
performance reasons I want to download all the slides and polls in one
shot when reading the carousel.

So far so good - Piston automatically follows the FK relationships and
includes the Slides and the polls. The problem is that it uses the
fields defined on the PollHandler when filling in the Poll data. But
I don't want to send all those fields, just a subset.

Things I've tried:

- specifying the fields directly in the CarouselHandler (e.g.
('title', ('slide_set' ('pk', ('poll' ('field I want'))))). This
works fine if the PollHandler hasn't been loaded, but not if it has
- Looked at list_fields, but that doesn't apply here because the Poll
relationship isn't a field

Looking through the code, it seems that there's a decision made in
emitter.py to prioritise fields from a handler over fields directly
declared:

def _model(data, fields=None):
"""
Models. Will respect the `fields` and/or
`exclude` on the handler (see `typemapper`.)
"""
ret = { }
handler = self.in_typemapper(type(data), self.anonymous)
get_absolute_uri = False

if handler or fields:
v = lambda f: getattr(data, f.attname)

if handler:
fields = getattr(handler, 'fields')

What is the reason behind this? It seems to me that if the test was
the other way round, then if you included a FK without defining the
fields you wanted (e.g. fields = ('poll',....) you'd get the default
from the Handler for that model, but if you did want to limit the
fields on a specific API you could by doing fields = (...(poll, ('some
fields')).

So the question is - is there a way to do what I want, or should I
just invert the test in emitters.py?

I've also been bitten by the subtlety that the output of an API can
depend on what order URLs are called, since my handlers are being
initialised in urls.py files that are included by the master urls.py.
So e.g. the URLconf for /api/poll is in polls/urls.py and the URLconf
for /api/carousel is in carousel/urls.py. Therefore whether the
PollHandler is registered in the typemapper depends on whether the /
api/poll URL has been hit.

This seems like I'm probably using this the wrong way - what's the
recommendation for where handlers are created?

Cheers,

Malcolm
Reply all
Reply to author
Forward
0 new messages