Issue with ManyToManyField while PUTting resource
I am trying to PUT an update of my resource using the following CURL request:
curl 'http://localhost:8000/resources/1/' -X PUT -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0' -H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Referer: http://localhost:9000/mentor-dashboard/mentor-resource-edit/@http~@~_~_localhost~@8000~_resources~_1~_' -H 'Content-Type: application/ld+json' -H 'If-Match: undefined' -H 'Origin: http://localhost:9000' -H 'Connection: keep-alive' -H 'Cookie: csrftoken=of6ls8iPnj2R7yldkWg54rtTpHSmXP5FGusV7LzobgxkJwpyuITVOQe12jppxf73; sessionid=40a725pbu64bng8j48f0bnjewmavj7gt' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache' --data '[
{
"@id": "http://localhost:8000/resources/1/",
"http://happy-dev.fr/owl/#author": "Alex Osterwald",
"http://happy-dev.fr/owl/#country": "France",
"http://happy-dev.fr/owl/#description": "Pellentesque urna neque, posuere ac vulputate et, rhoncus ut nisi. Etiam at ligula eget orci viverra fermentum id pellentesque ante.",
"http://happy-dev.fr/owl/#field": [
{
"@id": "http://localhost:8000/fields/3/"
},
{
"@id": "http://localhost:8000/fields/7/"
}
],
"http://happy-dev.fr/owl/#format": {
"@id": "http://localhost:8000/formats/1/"
},
"http://happy-dev.fr/owl/#header_access": "",
"http://happy-dev.fr/owl/#header_classification": "",
"http://happy-dev.fr/owl/#header_complementary": "",
"http://happy-dev.fr/owl/#header_mandatory": "",
"http://happy-dev.fr/owl/#header_related": "",
"http://happy-dev.fr/owl/#iframe_link": "",
"http://happy-dev.fr/owl/#language": {
"@id": "http://localhost:8000/languages/1/"
},
"http://happy-dev.fr/owl/#preview_image": "",
"http://happy-dev.fr/owl/#publication_year": 2000,
"http://happy-dev.fr/owl/#related": {
"@id": "http://localhost:8000/resources/2/"
},
"http://happy-dev.fr/owl/#sharing": "",
"http://happy-dev.fr/owl/#skills": "Is vulputate. Aliquam mollis consectetur enim, et aliquet lorem. Fusce quis placerat urna. Vestibulum pharetra rhoncus felis at mollis. Mauris purus diam, iaculis at massa vel, lacinia sollicitudin mauris. Nullam ultricies, ligula quis varius aliquam, eros mi ultric",
"http://happy-dev.fr/owl/#steps": {
"@id": "http://localhost:8000/steps/4/"
},
"http://happy-dev.fr/owl/#tags": "",
"http://happy-dev.fr/owl/#target": "public",
"http://happy-dev.fr/owl/#type": {
"@id": "http://localhost:8000/types/1/"
},
"http://happy-dev.fr/owl/#uri": "https://www.strategyzer.com/books/value-proposition-design",
"http://www.w3.org/2000/01/rdf-schema#label": "Value proposition design"
}
]'
The PUT request is stalled, as I got an error on the server side:
[01/Sep/2019 08:01:59] "OPTIONS /resources/1/ HTTP/1.1" 200 256
Internal Server Error: /resources/1/
Traceback (most recent call last):
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: coopstarter_data_resource_format.resource_id, coopstarter_data_resource_format.format_id
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/balessan/.local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/home/balessan/.local/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/balessan/.local/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/balessan/.local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/balessan/.local/lib/python3.6/site-packages/rest_framework/viewsets.py", line 114, in view
return self.dispatch(request, *args, **kwargs)
File "/home/balessan/.local/lib/python3.6/site-packages/djangoldp/views.py", line 204, in dispatch
response = super(LDPViewSet, self).dispatch(request, *args, **kwargs)
File "/home/balessan/.local/lib/python3.6/site-packages/rest_framework/views.py", line 497, in dispatch
response = self.handle_exception(exc)
File "/home/balessan/.local/lib/python3.6/site-packages/rest_framework/views.py", line 457, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/balessan/.local/lib/python3.6/site-packages/rest_framework/views.py", line 468, in raise_uncaught_exception
raise exc
File "/home/balessan/.local/lib/python3.6/site-packages/rest_framework/views.py", line 494, in dispatch
response = handler(request, *args, **kwargs)
File "/home/balessan/.local/lib/python3.6/site-packages/djangoldp/views.py", line 153, in update
self.perform_update(serializer)
File "/home/balessan/.local/lib/python3.6/site-packages/rest_framework/mixins.py", line 78, in perform_update
serializer.save()
File "/home/balessan/.local/lib/python3.6/site-packages/rest_framework/serializers.py", line 208, in save
self.instance = self.update(self.instance, validated_data)
File "/home/balessan/.local/lib/python3.6/site-packages/djangoldp/serializers.py", line 526, in update
self.save_or_update_nested_list(instance, nested_fields)
File "/home/balessan/.local/lib/python3.6/site-packages/djangoldp/serializers.py", line 599, in save_or_update_nested_list
manager.add(saved_item)
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 931, in add
self._add_items(self.source_field_name, self.target_field_name, *objs)
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 1100, in _add_items
for obj_id in new_ids
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/models/query.py", line 442, in bulk_create
ids = self._batched_insert(objs_without_pk, fields, batch_size)
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/models/query.py", line 1083, in _batched_insert
self._insert(item, fields=fields, using=self.db)
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/models/query.py", line 1060, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1099, in execute_sql
cursor.execute(sql, params)
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/backends/utils.py", line 80, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/balessan/.local/lib/python3.6/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/home/balessan/.local/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: coopstarter_data_resource_format.resource_id, coopstarter_data_resource_format.format_id
The mentioned field (format, on the resource model), is defined as follows:
format = models.ManyToManyField(Format, blank=True, related_name='resources')
I defined no specific unicity constraint or anything. I got the error when I am pushing a not-modified format @id. If I push a new one, but only one, it works.
For this given resource:
{
"@id":"http://localhost:8000/resources/1/",
"name":"Value proposition design",
"description":"Pellentesque urna neque, posuere ac vulputate et, rhoncus ut nisi. Etiam at ligula eget orci viverra fermentum id pellentesque ante.",
"skills":"Is vulputate. Aliquam mollis consectetur enim, et aliquet lorem. Fusce quis placerat urna. Vestibulum pharetra rhoncus felis at mollis. Mauris purus diam, iaculis at massa vel, lacinia sollicitudin mauris. Nullam ultricies, ligula quis varius aliquam, eros mi ultric",
"author":"Alex Osterwald",
"target":"public",
"uri":"https://www.strategyzer.com/books/value-proposition-design",
"publication_year":2000,
"format":{
"@id":"http://localhost:8000/resources/1/format/",
"@type":"ldp:Container",
"ldp:contains":[
{
"@id":"http://localhost:8000/formats/1/"
}
],
"permissions":[
{
"mode":{
"@type":"view"
}
}
]
},
"conversations":{
"@id":"http://localhost:8000/resources/1/conversations/",
"@type":"ldp:Container",
"ldp:contains":[
],
"permissions":[
{
"mode":{
"@type":"add"
}
},
{
"mode":{
"@type":"view"
}
}
]
},
"steps":{
"@id":"http://localhost:8000/resources/1/steps/",
"@type":"ldp:Container",
"ldp:contains":[
{
"@id":"http://localhost:8000/steps/4/"
},
{
"@id":"http://localhost:8000/steps/4/"
},
{
"@id":"http://localhost:8000/steps/4/"
},
{
"@id":"http://localhost:8000/steps/4/"
},
{
"@id":"http://localhost:8000/steps/4/"
}
],
"permissions":[
{
"mode":{
"@type":"view"
}
}
]
},
"language":{
"@id":"http://localhost:8000/languages/1/"
},
"fields":{
"@id":"http://localhost:8000/resources/1/fields/",
"@type":"ldp:Container",
"ldp:contains":[
{
"@id":"http://localhost:8000/fields/7/"
}
],
"permissions":[
{
"mode":{
"@type":"view"
}
}
]
},
"type":{
"@id":"http://localhost:8000/types/1/"
},
"submitter":{
"@id":"http://localhost:8000/users/4/"
},
"related":{
"@id":"http://localhost:8000/resources/1/related/",
"@type":"ldp:Container",
"ldp:contains":[
{
"@id":"http://localhost:8000/resources/2/"
}
],
"permissions":[
{
"mode":{
"@type":"add"
}
},
{
"mode":{
"@type":"view"
}
}
]
},
"likes":{
"@id":"http://localhost:8000/resources/1/likes/",
"@type":"ldp:Container",
"ldp:contains":[
],
"permissions":[
{
"mode":{
"@type":"add"
}
},
{
"mode":{
"@type":"view"
}
}
]
},
"reviews":{
"@id":"http://localhost:8000/resources/1/reviews/",
"@type":"ldp:Container",
"ldp:contains":[
],
"permissions":[
{
"mode":{
"@type":"add"
}
},
{
"mode":{
"@type":"view"
}
}
]
},
"@type":"coopstarter:resource",
"permissions":[
{
"mode":{
"@type":"view"
}
},
{
"mode":{
"@type":"change"
}
},
{
"mode":{
"@type":"control"
}
},
{
"mode":{
"@type":"delete"
}
}
],
"@context":"https://cdn.happy-dev.fr/owl/hdcontext.jsonld"
}
Sending this format information fails:
{
"0":{
"@id":"http://localhost:8000/resources/1/",
"http://happy-dev.fr/owl/#author":"Alex Osterwald",
"http://happy-dev.fr/owl/#country":"France",
"http://happy-dev.fr/owl/#description":"Pellentesque urna neque, posuere ac vulputate et, rhoncus ut nisi. Etiam at ligula eget orci viverra fermentum id pellentesque ante.",
"http://happy-dev.fr/owl/#field":[
{
"@id":"http://localhost:8000/fields/3/"
},
{
"@id":"http://localhost:8000/fields/7/"
}
],
"http://happy-dev.fr/owl/#format":{
"@id":"http://localhost:8000/formats/1/"
},
"http://happy-dev.fr/owl/#header_access":"",
"http://happy-dev.fr/owl/#header_classification":"",
"http://happy-dev.fr/owl/#header_complementary":"",
"http://happy-dev.fr/owl/#header_mandatory":"",
"http://happy-dev.fr/owl/#header_related":"",
"http://happy-dev.fr/owl/#iframe_link":"",
"http://happy-dev.fr/owl/#language":{
"@id":"http://localhost:8000/languages/1/"
},
"http://happy-dev.fr/owl/#preview_image":"",
"http://happy-dev.fr/owl/#publication_year":2000,
"http://happy-dev.fr/owl/#related":{
"@id":"http://localhost:8000/resources/2/"
},
"http://happy-dev.fr/owl/#sharing":"",
"http://happy-dev.fr/owl/#skills":"Is vulputate. Aliquam mollis consectetur enim, et aliquet lorem. Fusce quis placerat urna. Vestibulum pharetra rhoncus felis at mollis. Mauris purus diam, iaculis at massa vel, lacinia sollicitudin mauris. Nullam ultricies, ligula quis varius aliquam, eros mi ultric",
"http://happy-dev.fr/owl/#steps":{
"@id":"http://localhost:8000/steps/4/"
},
"http://happy-dev.fr/owl/#tags":"",
"http://happy-dev.fr/owl/#target":"public",
"http://happy-dev.fr/owl/#type":{
"@id":"http://localhost:8000/types/1/"
},
"http://happy-dev.fr/owl/#uri":"https://www.strategyzer.com/books/value-proposition-design",
"http://www.w3.org/2000/01/rdf-schema#label":"Value proposition design"
}
}
But this one works:
{
"0":{
"@id":"http://localhost:8000/resources/1/",
"http://happy-dev.fr/owl/#author":"Alex Osterwald",
"http://happy-dev.fr/owl/#country":"France",
"http://happy-dev.fr/owl/#description":"Pellentesque urna neque, posuere ac vulputate et, rhoncus ut nisi. Etiam at ligula eget orci viverra fermentum id pellentesque ante.",
"http://happy-dev.fr/owl/#field":[
{
"@id":"http://localhost:8000/fields/3/"
},
{
"@id":"http://localhost:8000/fields/7/"
}
],
"http://happy-dev.fr/owl/#format":{
"@id":"http://localhost:8000/formats/3/"
},
"http://happy-dev.fr/owl/#header_access":"",
"http://happy-dev.fr/owl/#header_classification":"",
"http://happy-dev.fr/owl/#header_complementary":"",
"http://happy-dev.fr/owl/#header_mandatory":"",
"http://happy-dev.fr/owl/#header_related":"",
"http://happy-dev.fr/owl/#iframe_link":"",
"http://happy-dev.fr/owl/#language":{
"@id":"http://localhost:8000/languages/1/"
},
"http://happy-dev.fr/owl/#preview_image":"",
"http://happy-dev.fr/owl/#publication_year":2000,
"http://happy-dev.fr/owl/#related":{
"@id":"http://localhost:8000/resources/2/"
},
"http://happy-dev.fr/owl/#sharing":"",
"http://happy-dev.fr/owl/#skills":"Is vulputate. Aliquam mollis consectetur enim, et aliquet lorem. Fusce quis placerat urna. Vestibulum pharetra rhoncus felis at mollis. Mauris purus diam, iaculis at massa vel, lacinia sollicitudin mauris. Nullam ultricies, ligula quis varius aliquam, eros mi ultric",
"http://happy-dev.fr/owl/#steps":{
"@id":"http://localhost:8000/steps/4/"
},
"http://happy-dev.fr/owl/#tags":"",
"http://happy-dev.fr/owl/#target":"public",
"http://happy-dev.fr/owl/#type":{
"@id":"http://localhost:8000/types/1/"
},
"http://happy-dev.fr/owl/#uri":"https://www.strategyzer.com/books/value-proposition-design",
"http://www.w3.org/2000/01/rdf-schema#label":"Value proposition design"
}
}
I thought I would have the issue with any of my ManyToManyFields but only the format one is raising errors.
Current complete version of my resource model can be found here.
CC @sylvain