In my model I test some constraints that rely on field that's added by the ListCreateAPIView's pre_save method, however since the models's clean method is called before it, I get a DoesNotExist exception when I try to access self.owner. Is this the indented order?
owner = models.ForeignKey('auth.User', related_name='cars')
def clean(self, *args, **kwargs):
super(Car, self).clean(*args, **kwargs)
querySet = self.__class__._default_manager.filter(owner=self.owner)
def pre_save(self, obj):
obj.owner = self.request.user
Can see the issue yup, but I'm not sure what'd be a good we to resolve it.
At the moment the object isn't available on the serializer until after .is_valid() has been called, so you can't call pre_save until after that's happened.
Was this ever resolved?
@asc89 Nope. It might be useful to have someone rephrase the problem they are seeing - this ticket always confuses me a little.
I'm running into something very similar to this ticket. In our Django model's clean() method we're accessing a field (owner)that is being set in the pre_save() method of the ModelViewSet. This leads to a DoesNotExist exception in the clean(). Is there any other hook (other than overriding the create(), where I could be setting the owner by pulling it from the request so that it is there when clean() gets called?
I worked around this problem by overriding restore_fields and restore_object in my ModelSerializer subclass.
If you have an owner model in the request, you'd do something like this:
def restore_fields(self, data, files):
owner = self.context['request'].owner
if data and not 'owner' in data:
Make sure owner is available in data, in case the owner attribute is NOT an excluded field.
d = data.copy()
d['owner'] = owner.pk
data = d
reverted_data = super(OwnedModelSerializer, self).restore_fields(data, files)
if not 'owner' in reverted_data:
Owner field is excluded, and thus ignored by restore_fields.
Let's force it to be present anyway.
reverted_data['owner'] = owner
def restore_object(self, attrs, instance=None):
The attrs parameter is basically the reverted_data returned by restore_fields.
ret = super(OwnedModelSerializer, self).restore_object(attrs, instance)
if ret == attrs: # I think this is true in case of errors, not sure
ret.owner = attrs['owner']
Hoping the 3.0 redesign will help resolve this, as the serializer changes will also affect the default pre_save implementation.
Closing pending 3.0 - feel free to reopen if it does not resolve the issue.
Also marking this with the Serializer to ensure it gets a further review prior to release.