Dustin Wyatt
Dustin Wyatt

Reputation: 4244

With django-rest-framework how do I assign a field to the request user when using a ModelViewSet?

The documentation recommends for APIViews:

def pre_save(self, obj):
    obj.owner = self.request.user

This doesn't seem to work as I get back:

{
    "owner": [
        "This field cannot be null."
    ]
}

edit: The pre_save method never gets called. Checked by inserting a call to pdb in the pre_save method.

My serializer is a plain HyperlinkedModelSerializer with the model and list of fields specified in Meta.

Upvotes: 1

Views: 270

Answers (4)

Jocelyn delalande
Jocelyn delalande

Reputation: 5394

Check DRF 3.0 release notes docs. They have an example doing exactly what you need with perform_create() in ViewSet .

Upvotes: 1

Dustin Wyatt
Dustin Wyatt

Reputation: 4244

On my model I had overridden clean_fields. The signature for clean_fields:

Model.clean_fields(exclude=None)

My custom clean_fields:

def clean_fields(self, exclude=None):
    super(Applicant, self).clean_fields()  # Bug here.  
    # custom clean_fields code

I didn't pass the exclude parameter to the super class!

Oh god this took me so many hours to debug.

Upvotes: 1

timop
timop

Reputation: 942

The problem seems to be that the validation fails because the "owner" field is required but not given a value in the initial data(it gets a value after validation). Because serializer.is_valid() is run before pre_save() then it fails.

Why the version change fixes it I have no idea. I myself have set owner as required=False although an object always will get one from pre_save()

Upvotes: 0

Paulo Scardine
Paulo Scardine

Reputation: 77251

Include the "owner" field in the serializer Meta.exclude (or just remove it from the field list if you are using the "positive" list).

class FooSerializer(serializers.Serializer):
    class Meta(object):
        model: Foo
        exclude: ('owner',)

This way you will not trigger validation for this field. Also, make sure the endpoint is decorated with mandatory authentication or check if self.request.user.is_authenticated() is True.

Upvotes: 0

Related Questions