Inconsistent behaviour of model representations?

Issue #64 resolved
Steve Jalim
created an issue

Hi Jesper

(I've put this to the Google Group too, but just in case you don't check that as often as tickets. Hope you don't mind.)

These could be two separate issues, but...

Say I've got a Foo model, which is exposed under /foos/ for Foo.objects.all() and /foo/{id}/ for specific Foos. That's all fine and seems to work fine and consistently.

My users have m2m relations with Foo, so if i expose the User object, and include 'foos' in fields(), I get a reference in my XML to the instance of the m2m manager. Anyone know if that's an issue with Piston's construct() method, or is it more likely to be with my ElementTree-based XML render() method?

Anyway, to get around it, I define a @classmethod which goes and gets the Foos associated with the User.

Now, this works sometimes, but not always. In the sense of I can request /user/1/ and get the user details including a representation of their Foos, but then I refresh and just get the core user details and not the associated Foos. Once this starts happening, I can't get back to the 'correct' representation which includes the Foos.

Has anyone come across this kind of issue? Is it that the lookup or construct() method is failing and returning the Foo.manager instead of the objects?

What might cause the inconsistency/What kind of model-related caching is going on? Any advice about debugging would be welcome. :o)

(FWIW, I'm doing the BaseHandler.fields = AnonymousBaseHandler.fields = () trick to ensure I have no 'inherited' behaviour across resources involving similar models)

Cheers Steve

Comments (8)

  1. Steve Jalim reporter


    I realise that if piston is given an absent field in fields=(), or if the classmethod used to create an additional field is flawed, Piston silently swallows the exception and renders the rest of the stuff. Is this perhaps related to my issue?

    Cheers Steve

  2. Steve Jalim reporter

    Hi Jesper - thanks for the prompt reply!

    Ah, right - I've looked back and checked and while I only use model = Foo in one place in my codebase, I had three user-related handlers which have model=User, but the fields = ('xxx', 'yyyy', 'zzzz') setup didn't match.

    So, I changed them to match, and still had problems, but then pulled out the model= and fields= of two handlers that don't actually need self.model to do what they do (they're just firing contrib.auth.login() and logout() using request after piston's done http basic auth for me).

    Now, it seems to consistently work, which is great. However, it's left me thinking that the option to override model fields on a per-handler basis isn't possible.

    However, I get that the docs ( don't actually say you can set model = Foo in several places, only that you can choose a subset of fields in other handlers, which presumably have their self.model as a different model, yep?

    If different ranges of fields across different handlers for the same model isn't possible, that's fine - better to know and work with that rather than fight it :o)

    Cheers for your time


  3. Steve Jalim reporter

    PS - I realise, btw, that a uniform representation of a resource is definitely better than a variable one, but this is just for cases when I'm trying to reduce XML payload

  4. Jesper Noehr repo owner

    There's a few problems when using differing field's with the same model in several places, but they're hard to run into. You've managed to hit them hard, and I suspect it's due to the high level of customization you've done.

    Piston (apparently) doesn't deal well with that, and I don't see a simple way to make it understand. You're more than welcome to contribute patches :-)

  5. Steve Jalim reporter

    HI Jesper

    Yeah, you could be right. It seems to be under control right now using the existing piston API, but if i find real need to tinker with the code (and have time to!), I'll happily contribute patches, for sure.

    There's definitely an issue where if Foo has an m2m to User, a field called 'foos' in a handler for User returns the m2m manager, and not the user.foos.all(). If I work out why, I'll let you know ;o) Or can that be sorted with nesting?

    Cheers Steve

  6. Log in to comment