-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UniqueValidator raises exception for nested objects #2403
Comments
It's a constraint that needs to be properly documented, yes. The best thing to do would be to instead write any validation in the top level serializer class, in the If you wanted to give your serializers as an example I might be able to demonstrate how you'd do that. Shame that there's nothing more we can really do about this, but writable nested serializers are inherently awkward cases. |
@tomchristie
That said, I am having difficulty to implement this myself becaue it seems that not enough context (about the nested serializer's data) is passed to the UniqueValidator. Field validators are only passed the value for the field, but, as in this case, it may also be useful to get passed the full data passed to the serializer containing the field. If I am missing some important information here, could you please give some hint? So, what is your opinion on this? |
Good news for everyone dealing with writable nested model serializers and interested in bypassing the restriction with UniqueValidator. Based on the concept on my previous post, I have come up with the following workaround, which is overriding the model serializer's to_internal_value() method. def to_internal_value(self, data):
if 'id' in data and 'id' in self.fields:
try:
obj_id = self.fields['id'].to_internal_value(data['id'])
except ValidationError as exc:
raise ValidationError({'id': exc.detail})
for field in self.fields.values():
for validator in field.validators:
if type(validator) == UniqueValidator:
# Exclude id from queryset for checking uniqueness
validator.queryset = validator.queryset.exclude(id=obj_id)
return super(WritableNestedModelSerializer, self).to_internal_value(data) (ValidationError must be imported from rest_framework.serializers and UniqueValidator from rest_framework.validators) It is assumed that the model serializer has a writable 'id' field for the model's primary key field, which is also named 'id' (as usual with django models). In my case, all models have a field named 'id' as their primary key, so the above works perfectly for me, but it's not difficult to generalize this for whatever the primary key field is named both in the model and the serializer. |
Not had time to properly review, but marking as 'Needs design decision' to keep it visible. |
I think I'm encountering this issue. (I'm a newbie to DRF, so not very sure...) I have a model Person that contains a OneToOneField pointing to User model. I am trying to use nested model serializers to create/retrieve/update them. I am able to perform GET/POST operations using the browsable APIs, but when I try to update an existing Person object using PUT, I encounter the error: What are my options at this point, if indeed this is the same issue? |
You can read my post above for a workaround. Keep in mind that my workaround requires that you include 'id' as a writable field in the serializer. |
Since I'm using ModelSerializer, the UserSerializer that I've generated from User model has id field as read-only by default. I haven't figured out how to make the id field writable. However, would it be safe to expose the id field of Django's User object model as a writable field?? |
@tanuka72 I'd consider dropping |
Thanks, will try that. |
Put an "extra_kwargs" attribute in the Meta class of your ModelSerializer subclass like this:
|
That'll also work yes. Either way around it's a case over overriding the default field that's generated. |
@Ernest0x Yes, your workaround works for me now. @tomchristie I really like the concept of writable nested model serializers as a concise way of presenting/updating related models in one shot. I'm trying to mimic what I've done before by combining multiple ModelForms in a single template. What would be the most elegant and DRY way to do that using DRF? |
@tomchristie I replaced my ModelSerializers with explicit serializers (nested), and am facing a different issue now. Rather than confuse this thread, I've posted it on StackOverflow: Am I doing something wrong, or encountering a known problem? |
When the serializer is nested the unique validator on registration_id does not behave correctly. This is a known issue with DRF see: encode/django-rest-framework#2403 Added missing allow_null to device_id field Fixes jazzband#270
When the serializer is nested the unique validator on registration_id does not behave correctly. This is a known issue with DRF see: encode/django-rest-framework#2403 Added missing allow_null to device_id field Fixes jazzband#270
When the serializer is nested the unique validator on registration_id does not behave correctly. This is a known issue with DRF see: encode/django-rest-framework#2403 Added missing allow_null to device_id field Fixes jazzband#270
When the serializer is nested the unique validator on registration_id does not behave correctly. This is a known issue with DRF see: encode/django-rest-framework#2403 Added missing allow_null to device_id field Fixes jazzband#270
Closing as duplicated issue - Also tracking this as |
When the serializer is nested the unique validator on registration_id does not behave correctly. This is a known issue with DRF see: encode/django-rest-framework#2403 Added missing allow_null to device_id field Fixes #270
I have a model Service which has contains a ForeignKey to atSifrantStoritev_model.
Using ModelViewSet for Service andatSifrantStoritev_model models the update for the object of type Service fails with the folloving data.
I traced the source of the exception to the function
in the validators.py file. The method fails to remove a currenttSifrantStoritev_model object since self.instance equals to None. Could this be a bug in Django Rest validation system or am I missing something?
The text was updated successfully, but these errors were encountered: