Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Extra Fields on POST
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  14 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Carlton Gibson  
View profile  
 More options Nov 16 2012, 11:09 am
From: Carlton Gibson <carlton.gib...@gmail.com>
Date: Fri, 16 Nov 2012 17:08:56 +0100
Local: Fri, Nov 16 2012 11:08 am
Subject: Extra Fields on POST
Hi All,

Following the tutorial we have a serializer and view:

class UserSerializer(serializers.HyperlinkedModelSerializer):
   class Meta:
       model = User
       fields = ('url', 'username', 'email', 'groups')

class UserList(generics.ListCreateAPIView):
   """
   API endpoint that represents a list of users.
   """
   model = User
   serializer_class = UserSerializer

We'd like to allow the creation of a User with a password field but (obviously) not reveal this over the API.

1. (How) can we allow the extra filed on POST (or do we need separate Serializers/Views)?
2. Do we need to override the post method to apply the correct salt/hashing?

Thanks in advance.

Regards,

Carlton


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tom Christie  
View profile  
 More options Nov 16 2012, 12:42 pm
From: Tom Christie <christie....@gmail.com>
Date: Fri, 16 Nov 2012 09:42:50 -0800 (PST)
Local: Fri, Nov 16 2012 12:42 pm
Subject: Re: Extra Fields on POST

Hi Carlton,

> 1. (How) can we allow the extra filed on POST (or do we need separate

Serializers/Views)?

  For this use case you probably want to write the APIView yourself,
without relying on the Generic Views.
All of the Generic views use the same serializer for validating the input,
and serializing the output, which is fine in most cases, but doesn't quite
work here.

  In your custom APIView, you'll probably want one serializer (which does
include a password field) that you use for validating the input, and then a
second for actually serializing the user (which doesn't).

  I'd suggest taking a dig around the existing create/update code<https://github.com/tomchristie/django-rest-framework/blob/master/rest...>as it's actually very simple.

> 2. Do we need to override the post method to apply the correct

salt/hashing?

  Because creating users is a little different to the usual case of
creating a model instance due to the password saving, you probably want to
look at overriding the 'restore_object` method on the serializer

See:
http://django-rest-framework.org/api-guide/serializers.html#declaring...

I guess it'd be something like:

    def restore_object(self, attrs, instance=None):
    if instance:  #Update
        user = instance
        user.username = attrs['username']

        user.email = attrs['email']
     else:

                user = User(username=attrs['username'], email=attrs['email']
,
                is_staff=False, is_active=True, is_superuser=False)
   user.set_password(password)
   user.save()
return user

Hope that helps.  If you get it working okay, I'd really like to see what
you end up with as I think this one is probably a reasonable common case
for folks to bump into.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Carlton Gibson  
View profile  
 More options Nov 16 2012, 12:53 pm
From: Carlton Gibson <carlton.gib...@gmail.com>
Date: Fri, 16 Nov 2012 18:53:27 +0100
Local: Fri, Nov 16 2012 12:53 pm
Subject: Re: Extra Fields on POST

Hi Tom,

Thanks for the quick reply — that gives me lots to play with over the weekend. :-)

On 16 Nov 2012, at 18:42, Tom Christie <christie....@gmail.com> wrote:

>   I'd suggest taking a dig around the existing create/update code as it's actually very simple.

I've been digging around quite a lot — it all seems quite simple really — which is testament to how well thought through it is.
(Thank you!)

>   If you get it working okay, I'd really like to see what you end up with as I think this one is probably a reasonable common case for folks to bump into.

I'll come back with my solution.
(The least I can do.)

Have a good weekend all!

Regards,

Carlton


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tom Christie  
View profile  
 More options Nov 16 2012, 1:01 pm
From: Tom Christie <christie....@gmail.com>
Date: Fri, 16 Nov 2012 18:03:24 +0000
Local: Fri, Nov 16 2012 1:03 pm
Subject: Re: Extra Fields on POST

Oh another thought: you might consider simply using a different endpoint for setting the users password. That might work out more simply.

On 16 Nov 2012, at 17:53, Carlton Gibson <carlton.gib...@gmail.com> wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Carlton Gibson  
View profile  
 More options Nov 21 2012, 3:41 pm
From: Carlton Gibson <carlton.gib...@gmail.com>
Date: Wed, 21 Nov 2012 21:41:13 +0100
Local: Wed, Nov 21 2012 3:41 pm
Subject: Re: Extra Fields on POST

Hi all,

On 16 Nov 2012, at 18:42, Tom Christie <christie....@gmail.com> wrote:

> > 1. (How) can we allow the extra filed on POST (or do we need separate Serializers/Views)?

>   For this use case you probably want to write the APIView yourself, without relying on the Generic Views.
> All of the Generic views use the same serializer for validating the input, and serializing the output, which is fine in most cases, but doesn't quite work here.

>   In your custom APIView, you'll probably want one serializer (which does include a password field) that you use for validating the input, and then a second for actually serializing the user (which doesn't).

>   I'd suggest taking a dig around the existing create/update code as it's actually very simple.

Just following up on this: I haven't written it yet but it is on the list. In the meantime I think I have the opposite problem.

I have a model with an "updated" field which is:

    updated = models.DateTimeField(auto_now=True)

DRF is making me provide a (valid) value even though it will never be used.

Here I want "Fewer Fields on POST".

_And_ I can see this sort of thing coming up all the time.

(Just another case, I have a list endpoint that I want users to POST to but on admins GET.) It seems to me it would be good to be able to tweak the serializers somehow to still be able to use the generic views.

(Am on it but am hoping to fire-up more/better brains than merely mine.)

Regards,

Carlton


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tom Christie  
View profile  
 More options Nov 22 2012, 8:00 am
From: Tom Christie <christie....@gmail.com>
Date: Thu, 22 Nov 2012 05:00:53 -0800 (PST)
Local: Thurs, Nov 22 2012 8:00 am
Subject: Re: Extra Fields on POST

It sounds like you're looking for the read_only=True argument unless I'm missing something.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Carlton Gibson  
View profile  
 More options Nov 22 2012, 8:13 am
From: Carlton Gibson <carlton.gib...@gmail.com>
Date: Thu, 22 Nov 2012 05:13:12 -0800 (PST)
Local: Thurs, Nov 22 2012 8:13 am
Subject: Re: Extra Fields on POST

On Thursday, 22 November 2012 14:00:53 UTC+1, Tom Christie wrote:

> It sounds like you're looking for the read_only=True argument unless I'm
> missing something.

No, I want the model to be writable via the endpoint — I just don't want
the `updated` field to be required (it's value is disregarded anyway). A
slight aside: this is the behaviour you get in the Admin, i.e. the updated
field wouldn't be shown.

The general problem seems to be needing different serializers — different
field lists — for different methods (plus, slightly different, perhaps
allowing differences depending on request.user too).

Your answer of writing the view by hand will no doubt work — and I need to
do it that way several times to grok everything — but I can see this kind
of thing coming up quite a lot. It would be nice to handle it with the
generic views.

(Perhaps we already can — but your original suggestion seemed to imply not.)

Anyhow, I just wanted to out the thought out there — mainly in case there's
something obvious I've missed. I'm working on it currently so I will come
back when I'm the other side of something that runs.

Regards,

Carlton


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Carlton Gibson  
View profile  
 More options Nov 22 2012, 8:21 am
From: Carlton Gibson <carlton.gib...@gmail.com>
Date: Thu, 22 Nov 2012 14:21:48 +0100
Local: Thurs, Nov 22 2012 8:21 am
Subject: Re: Extra Fields on POST

On Thursday, 22 November 2012 14:00:53 UTC+1, Tom Christie wrote:
> It sounds like you're looking for the read_only=True argument unless I'm missing something.

Aha! You meant the field argument.

http://django-rest-framework.org/api-guide/fields.html#core-arguments

Thank you!


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Rod Afshar  
View profile  
 More options Dec 1 2012, 6:50 pm
From: Rod Afshar <rafs...@gmail.com>
Date: Sat, 1 Dec 2012 15:50:14 -0800 (PST)
Local: Sat, Dec 1 2012 6:50 pm
Subject: Re: Extra Fields on POST

Just wanted to share how I went about tackling this. I have a similar need,
working with a model that has a `password_hash` field and accepts a
`password` through the API. I ended up using the restore_object and
convert_object methods of ModelSerializer to get it done and still rely on
the generic views. I was hoping to do it in a way that doesn't lose a lot
of the work that ModelSerializer does for you. Does this look like a decent
implementation?

*models.py*

class Account(models.Model):
    email = models.EmailField(unique=True, db_index=True, max_length=255)
    password_hash = models.CharField(max_length=255)

*serializers.py*

class AccountSerializer(serializers.ModelSerializer):
    password = serializers.CharField(widget=forms.PasswordInput())
    password_hash = serializers.CharField(read_only=True)

    created = serializers.DateTimeField(read_only=True)
    updated = serializers.DateTimeField(read_only=True)

    class Meta:
        model = Account

    def convert_object(self, obj):
        """Remove password field when serializing an object"""
        del self.fields['password']

        return super(AccountSerializer, self).convert_object(obj)

    def restore_object(self, attrs, instance=None):
        """Hash password field and remove it when deserializing"""
        attrs['password_hash'] = make_password(attrs['password'])
        del attrs['password']

        return super(AccountSerializer, self).restore_object(attrs,
instance=None)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Carlton Gibson  
View profile  
 More options Dec 8 2012, 4:35 pm
From: Carlton Gibson <carlton.gib...@gmail.com>
Date: Sat, 8 Dec 2012 13:35:31 -0800 (PST)
Local: Sat, Dec 8 2012 4:35 pm
Subject: Re: Extra Fields on POST

Hi All,

Sorry for the slow reply; I quickly went with the "second endpoint"
approach which delayed taking on the real problem.

On Sunday, 2 December 2012 00:50:14 UTC+1, Rod Afshar wrote:

> Just wanted to share how I went about tackling this.

I've bashed a working solution together combining Tom and Rod's approach.

I've added a ?set_password query parameter to the UserList view that
switches the serializer on POSTs:

class UserList(generics.ListCreateAPIView):
    """
    API endpoint that represents a list of users.
    """
    permission_classes = (permissions.IsAdminUserOrPostOnly,)
    model = User
    serializer_class = UserSerializer

    def post(self, request, *args, **kwargs):
        if request.QUERY_PARAMS.__contains__('set_password'):
            self.serializer_class = UserPasswordSerializer
        return self.create(request, *args, **kwargs)

(I'm not convinced by the whole query-string switch thing — it's more a
work-in-progress sticker.)

The UserPasswordSerializer looks like this:

class UserPasswordSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email','password')

    def convert_object(self, obj):
        """Remove password field when serializing an object"""
        del self.fields['password']

        return super(UserPasswordSerializer, self).convert_object(obj)

    def restore_object(self, attrs, instance=None):
        if instance:  #Update
            user = instance
            user.username = attrs['username']
            user.email = attrs['email']
        else:
            user = User(username=attrs['username'], email=attrs['email'],
               is_staff=False, is_active=True, is_superuser=False)
        user.set_password(attrs['password'])
        # note I don't save() here. The view's create() does that.
        return user

As I say, it's all work in progress (and all entirely derivative) but it
works with auth.User and (thus far) has the desired behaviour. I'll
continue working on it.

Regards,

Carlton


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Otto Yiu  
View profile  
 More options Jan 26, 9:49 pm
From: Otto Yiu <ottoyi...@gmail.com>
Date: Sat, 26 Jan 2013 18:49:33 -0800 (PST)
Local: Sat, Jan 26 2013 9:49 pm
Subject: Re: Extra Fields on POST

I'm still trying to find the best way to tackle this topic without creating
separate serializers or endpoints. I tried Rod's way, which seems like a
clean way in doing it. However, I get an exception when deleting the field
from the serializer in convert_object.

    def convert_object(self, obj):
        """Remove password field when serializing an object"""
        del self.fields['password']

Exception Type:KeyErrorException Value:

'password'

Exception Location:/home/bas/.virtualenv/backupcp-ws/lib/python2.7/site-packages/djan go/utils/datastructures.py
in __delitem__, line 137


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Carlton Gibson  
View profile  
 More options Jan 28, 3:55 am
From: Carlton Gibson <carlton.gib...@gmail.com>
Date: Mon, 28 Jan 2013 00:55:17 -0800 (PST)
Local: Mon, Jan 28 2013 3:55 am
Subject: Re: Extra Fields on POST

Maybe the user in question doesn't have a password set?

Try wrapping the del in a conditional:

        if 'password' in self.fields:
            del self.fields['password']

Regards,

Carlton


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Neamar Tucote  
View profile  
 More options Mar 18, 1:06 pm
From: Neamar Tucote <neam...@gmail.com>
Date: Mon, 18 Mar 2013 10:06:20 -0700 (PDT)
Local: Mon, Mar 18 2013 1:06 pm
Subject: Re: Extra Fields on POST

Hi,

Had the same problem, solved it by creating a special Field for password.
Hope this helps


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
julio.aleg...@ucsp.edu.pe  
View profile  
 More options Apr 18, 2:14 am
From: julio.aleg...@ucsp.edu.pe
Date: Wed, 17 Apr 2013 23:14:09 -0700 (PDT)
Local: Thurs, Apr 18 2013 2:14 am
Subject: Re: Extra Fields on POST

I've been on this problem all day. I read this and other threads but didn't
find something very practical. This is finally what I ended up doing:

http://pastebin.com/bkDBBR3b

Hopefully will be useful to someone else.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »