4

I have this model:

# models.py
from django.contrib.auth.models import User

class Test(models.Model):
    author = models.ForeignKey(User, related_name="tests")
    title = models.CharField(_("title"), max_length=100)

Then in the api folder for the django piston webservice:

class TestHandler(BaseHandler):
    allowed_methods = ("GET")
    model = Test
    fields = ("title", ("author", ("username",)))

    def read(self, request, id):
        base = self.model.objects
        try:
            r = base.get(pk=id)
            return r
        except:
            return rc.NOT_FOUND

If I call this webservice then I get:

{
    "title": "A test"
    "author": {
        "username": "menda", 
        "first_name": "", 
        "last_name": "", 
        "is_active": true, 
        "is_superuser": true, 
        "is_staff": true, 
        "last_login": "2011-02-09 10:39:02", 
        "password": "sha1$83f15$feb85449bdae1a55f3ad5b41a601dbdb35c844b7", 
        "email": "b@a.as", 
        "date_joined": "2011-02-02 10:49:48"
    },
}

I also have tried to use exclude, but it doesn't work either.

How can I get only the username for author? Thanks!

Menda
  • 1,783
  • 2
  • 14
  • 20
  • 1
    Your code looks right to me. In fact, I know this will be frustrating, but I copied your example exactly, and I'm getting only the author's username and the title in the response, exactly as you intended. The rest of the user info doesn't show up. (The nesting you have is right, by the way.) – mjjohnson Feb 09 '11 at 18:26

2 Answers2

2

Okay, so the problem is that Piston is using the set of fields defined on the User model by another Handler class, rather than the nested fields specified here.

Another user refers to the exact same issue on the piston discussion group here:

http://groups.google.com/group/django-piston/browse_thread/thread/295de704615ee9bd

The problem is apparently caused by bug in Piston's serialization code. In the words of the documentation:

By using a model in a handler, Piston will remember your fields/exclude directives and use them in other handlers who return objects of that type (unless overridden.)

Which is all good, except that the "(unless overridden.)" case doesn't seem to be handled correctly.

I think that a slight modification in emitters.py might fix the issue (lines 160-193)...

if handler:
    fields = getattr(handler, 'fields')                    
if not fields or hasattr(handler, 'fields'):
    ...dostuff...
else:
    get_fields = set(fields)

Which should (perhaps?) read

if fields:
    get_fields = set(fields)
else:
    if handler:
        fields = getattr(handler, 'fields')
    ...dostuff...

If you do decide to try patching emitters.py let me know if that does the trick - it'd be good to get this patched in django-piston.

Cheers!

Tom Christie
  • 33,394
  • 7
  • 101
  • 86
  • I don't have time right now to patch it and test it, but I'll send a bug ticket as soon as I can. Good answer :) – Menda Feb 11 '11 at 09:59
0

I think you're unnecessarily nesting the author field.

It looks like your fields attribute should instead read:

fields = ("title", "author", ("username",))

From the piston docs...

class UserHandler(BaseHandler):
      model = User
      fields = ('name', 'posts', ('title', 'date'))

will show the title and date from a users posts.
Tom Christie
  • 33,394
  • 7
  • 101
  • 86
  • Thanks, but it doesn't work either. I get a: "ValueError at /api/test/1/ Need more than 1 value to unpack". I think that my approach is correct. I'm reading the Piston doc and in the section "Configuring Handlers" he is using almost the same values than I'm using. – Menda Feb 09 '11 at 16:54
  • 1
    I don't suppose you're also exposing a Handler on User? I guess it's possible piston could be using the fields for that Handler instead. (See this post: http://groups.google.com/group/django-piston/browse_thread/thread/295de704615ee9bd) Having said that I couldn't replicate the behavior mentioned in that post, and I get the same correct response as peppergrower when I try your example. Failing that I guess make sure you've got the latest version of piston in case there was some old bug with the field handling that's now fixed... – Tom Christie Feb 10 '11 at 00:40
  • You where right tomc. Deleting other User handlers I have in my code solve this issue. I still don't understand why Piston is using these classes because they are completely different handlers. Post your answer separatelly and I'll mark it as correct. Thanks for helping! BTW, if you know why Piston is using my UserHandler and not only TestHandler it will be really nice. – Menda Feb 10 '11 at 09:59
  • Good stuff! See my new answer. If you've got the complete example that fails it might be worth throwing it up on a pastebin or something so I can take a proper look, have a stab at fixing emitters.py, and submitting the patch to django-piston. – Tom Christie Feb 10 '11 at 23:59