-
-
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
Unique constraint prevents nested serializers from updating #2996
Comments
It may be that we simply have to document this as a limitation in |
I'm a bit uncomfortable with this. |
We don't support (automatic) writable nested serialization, so it's not totally unreasonable to also say 'validators' are not appropraite for this case, here's what you'd need to do. However if there's an alternative that'd def be worth considering. |
This sounds very similar to the issue I ran into today: http://stackoverflow.com/questions/32123148/writable-nested-serializer-with-existing-objects-using-django-rest-framework-3-2 |
Arrgh, i've search for a day why was it not works!!! This is a really confusing issue, because it is a common thing to play with nested models, and i don't know how to get around of this problem ... I've got this :
And i must save a contact with an account, they are inseparable. How can i do this without this annoying unique validator message ? |
The discussion group is the best place to take this discussion and other usage questions. Thanks! |
So what is the way out? This to me seems like a major limitation.
|
The workaround this is to remove the unique constraint from the serializer and move it to the business logic validation part since the nested serializer can not say - as of today - whether he's updating or creating a new object. |
Guys, I've run into this problem, too. Just wanted to say that (unfortunately) without a generic WritableNestedModelSerializer out-of-the-box, Django REST framework is hardly useful. With hyperlinked APIs only, you often have to create chains of 3-4-5 consecutive POST/PUT ajax requests, which is waste of time. Writing one from scratch is problematic, repetitive and requires good knowledge of DRF internals. Much more importantly, if you want to expose your API to domain area specialists (e.g. bioinformaticians), they won't buy Hyperlinked one. They want a clear API with nested data structures and, to be honest, they are right. I''ve been studying the details of this for a couple of days now, got stuck on this error and not sure, whether I should continue messing with DRF internals or stop (breaking the deadlines) investing time into this and start learning Loopback. I'm pretty sure that with advent of update_or_create function in Django 1.7 it's possible to think out a generic way of nesting writable serializers. |
but can't the nested serializer figure out if it's updating an instance by checking parent.instance? |
@dedsm sure, but that would also break cases where the uniqueness constraint is broken on the "main" serializer and end up in 500 errors with database errors. |
Sorry I can't really tell from this thread; was this issue fixed? I'm trying to update a ManyToMany Field via nested serializer and it gets stuck on run_validators() because the relation object I'm trying to attach to my main object already exists. Would be nice to at least put the recommended workaround (with a few specifics) for a pretty common use case like this. |
|
I recently came across this issue (a user object attached to an account object via an intermediary relationship). Within the context of the account, I wanted to be able to update both the user details and the relationship details as a single endpoint. The problem being that the email field on the user model is unique and fell foul of the issue described here. I wasn't happy with breaking some very necessary validation, so I took a more direct approach. At the point of serializer initialisation, if the email supplied in the data is already the same as the email on the user, I simply removed it from the data. No change = no validation required*. def __init__(self, instance, data=empty, **kwargs):
if (
data is not empty and
'details.email' in data and
instance.user is not None and
instance.user.email == data['details.email']
):
del data['details.email']
super(AccountUserSerializer, self).__init__(instance, data=data, **kwargs)
|
@xordoquy, would that work?
|
The discussion group is the best place to take further this discussion and other usage questions. Thanks! |
I don't kwon if there is a documentation for this now, but i recently fix this problem with a basic zero validators on the field that cause the problem. |
I wrote some time ago an article about that if that helps: https://medium.com/django-rest-framework/dealing-with-unique-constraints-in-nested-serializers-dade33b831d9 |
- Fix tests with appropriate mock - Only update location info when created - Implement OrganizationSerializer create/update methods - Remove uniqueness constraint on location.api_city_id Removing the constraint was the lesser of two evils while we're interating quickly on the definition of this object. See: - encode/django-rest-framework#2996 - https://medium.com/django-rest-framework/dealing-with-unique-constraints-in-nested-serializers-dade33b831d9 Handling nested serializers with uniqueness constraints requires overriding the default validators generated for the entire serializer which is super inelegant. No harm to us for now if what are essentially duplicate planitlocation objects get created somehow.
- Add helper on PlanItUser model to get location - Fix tests with appropriate mock - Only update location info when created - Implement OrganizationSerializer create/update methods - Remove uniqueness constraint on location.api_city_id Removing the constraint was the lesser of two evils while we're interating quickly on the definition of this object. See: - encode/django-rest-framework#2996 - https://medium.com/django-rest-framework/dealing-with-unique-constraints-in-nested-serializers-dade33b831d9 Handling nested serializers with uniqueness constraints requires overriding the default validators generated for the entire serializer which is super inelegant. No harm to us for now if what are essentially duplicate planitlocation objects get created somehow.
there is this 3rd party library https://github.com/beda-software/drf-writable-nested, it has a UniqueFieldsMixin which can do the magic to handle unique constraints. |
for those ending up here => this SO answer helps |
Wow DRF , you guys should wake up |
Same problem here. Has it fixed yet ? |
you might try this and report back? |
@auvipy , I have used the package suggested (drf-writable-nested). It is actually so helpful. nothing to worry about updating multiple models through nested serializer. |
Has this been fixed yet? I tried doing the same thing today and the issue persists. I am using PrimaryKeyRelatedField as a workaround. |
If you have a nested serializer which model does have a unique constraint on a field you're not able to reference an existing instance.
Let's say I created a category & task which I'm updating with the very same data they already have:
The point is,
name
remains unique because it matches its ownid
The text was updated successfully, but these errors were encountered: