Relations#

Plone's relations represent binary relationships between content objects.

A single relation is defined by source, target, and relation name.

You can define relations either with content type schema fields RelationChoice or RelationList, or with types isReferencing or iterate-working-copy.

  • Relations based on fields of a content type schema are editable by users.

  • The relations isReferencing (block text links to a Plone content object) and iterate-working-copy (working copy is enabled and the content object is a working copy) are not editable. They are created and deleted with links in text, respectively creating and deleting working copies.

You can create, query, and delete relations by interacting through the @relations endpoint on the site root. Querying relations with the @relations endpoint requires the zope2.View permission on both the source and target objects. Therefore results include relations if and only if both the source and target are accessible by the querying user. Creating and deleting relations requires zope2.View permission on the target object and cmf.ModifyPortalContent permission on the source object.

Getting statistics for all relations#

The call without any parameters returns statistics on all existing relations to which the user has access.

http

GET /plone/@relations HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET http://nohost/plone/@relations -H "Accept: application/json" --user admin:secret

httpie

http http://nohost/plone/@relations Accept:application/json -a admin:secret

python-requests

requests.get('http://nohost/plone/@relations', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
HTTP/1.1 200 OK
Content-Type: application/json

{
    "@id": "http://localhost:55001/plone/@relations",
    "broken": {},
    "stats": {
        "comprisesComponentPart": 2,
        "relatedItems": 2
    }
}

Querying relations#

You can query relations by a single source, target, or relation type. Combinations are allowed. The source and target must be either a UID or path.

Queried relations require the View permission on the source and target. If the user lacks permission to access these relations, then they are omitted from the query results.

The relations are grouped by relation name, source, and target, and are provided in a summarized format.

Query relations of a relation type:

http

GET /plone/@relations?relation=comprisesComponentPart HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET 'http://nohost/plone/@relations?relation=comprisesComponentPart' -H "Accept: application/json" --user admin:secret

httpie

http 'http://nohost/plone/@relations?relation=comprisesComponentPart' Accept:application/json -a admin:secret

python-requests

requests.get('http://nohost/plone/@relations?relation=comprisesComponentPart', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
HTTP/1.1 200 OK
Content-Type: application/json

{
    "@id": "http://localhost:55001/plone/@relations?relation=comprisesComponentPart",
    "relations": {
        "comprisesComponentPart": {
            "items": [
                {
                    "source": {
                        "@id": "http://localhost:55001/plone/document",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000001",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 1",
                        "type_title": "Page"
                    },
                    "target": {
                        "@id": "http://localhost:55001/plone/document-2",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000002",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 2",
                        "type_title": "Page"
                    }
                },
                {
                    "source": {
                        "@id": "http://localhost:55001/plone/document",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000001",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 1",
                        "type_title": "Page"
                    },
                    "target": {
                        "@id": "http://localhost:55001/plone/document-3",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000003",
                        "description": "",
                        "review_state": "private",
                        "title": "Test document 3",
                        "type_title": "Page"
                    }
                }
            ],
            "items_total": 2,
            "readonly": false,
            "staticCatalogVocabularyQuery": null
        }
    }
}

Query relations of a source object by path:

http

GET /plone/@relations?source=/document HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET 'http://nohost/plone/@relations?source=/document' -H "Accept: application/json" --user admin:secret

httpie

http 'http://nohost/plone/@relations?source=/document' Accept:application/json -a admin:secret

python-requests

requests.get('http://nohost/plone/@relations?source=/document', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
HTTP/1.1 200 OK
Content-Type: application/json

{
    "@id": "http://localhost:55001/plone/@relations?source=/document",
    "relations": {
        "comprisesComponentPart": {
            "items": [
                {
                    "source": {
                        "@id": "http://localhost:55001/plone/document",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000001",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 1",
                        "type_title": "Page"
                    },
                    "target": {
                        "@id": "http://localhost:55001/plone/document-2",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000002",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 2",
                        "type_title": "Page"
                    }
                },
                {
                    "source": {
                        "@id": "http://localhost:55001/plone/document",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000001",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 1",
                        "type_title": "Page"
                    },
                    "target": {
                        "@id": "http://localhost:55001/plone/document-3",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000003",
                        "description": "",
                        "review_state": "private",
                        "title": "Test document 3",
                        "type_title": "Page"
                    }
                }
            ],
            "items_total": 2
        },
        "relatedItems": {
            "items": [
                {
                    "source": {
                        "@id": "http://localhost:55001/plone/document",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000001",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 1",
                        "type_title": "Page"
                    },
                    "target": {
                        "@id": "http://localhost:55001/plone/document-3",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000003",
                        "description": "",
                        "review_state": "private",
                        "title": "Test document 3",
                        "type_title": "Page"
                    }
                }
            ],
            "items_total": 1
        }
    }
}

Query relations of a source object by UID:

http

GET /plone/@relations?source=SomeUUID000000000000000000000001 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET 'http://nohost/plone/@relations?source=SomeUUID000000000000000000000001' -H "Accept: application/json" --user admin:secret

httpie

http 'http://nohost/plone/@relations?source=SomeUUID000000000000000000000001' Accept:application/json -a admin:secret

python-requests

requests.get('http://nohost/plone/@relations?source=SomeUUID000000000000000000000001', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
HTTP/1.1 200 OK
Content-Type: application/json

{
    "@id": "http://localhost:55001/plone/@relations?source=SomeUUID000000000000000000000001",
    "relations": {
        "comprisesComponentPart": {
            "items": [
                {
                    "source": {
                        "@id": "http://localhost:55001/plone/document",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000001",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 1",
                        "type_title": "Page"
                    },
                    "target": {
                        "@id": "http://localhost:55001/plone/document-2",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000002",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 2",
                        "type_title": "Page"
                    }
                },
                {
                    "source": {
                        "@id": "http://localhost:55001/plone/document",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000001",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 1",
                        "type_title": "Page"
                    },
                    "target": {
                        "@id": "http://localhost:55001/plone/document-3",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000003",
                        "description": "",
                        "review_state": "private",
                        "title": "Test document 3",
                        "type_title": "Page"
                    }
                }
            ],
            "items_total": 2
        },
        "relatedItems": {
            "items": [
                {
                    "source": {
                        "@id": "http://localhost:55001/plone/document",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000001",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 1",
                        "type_title": "Page"
                    },
                    "target": {
                        "@id": "http://localhost:55001/plone/document-3",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000003",
                        "description": "",
                        "review_state": "private",
                        "title": "Test document 3",
                        "type_title": "Page"
                    }
                }
            ],
            "items_total": 1
        }
    }
}

Query relations by relation name and source:

http

GET /plone/@relations?source=/document&relation=comprisesComponentPart HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET 'http://nohost/plone/@relations?source=/document&relation=comprisesComponentPart' -H "Accept: application/json" --user admin:secret

httpie

http 'http://nohost/plone/@relations?source=/document&relation=comprisesComponentPart' Accept:application/json -a admin:secret

python-requests

requests.get('http://nohost/plone/@relations?source=/document&relation=comprisesComponentPart', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
HTTP/1.1 200 OK
Content-Type: application/json

{
    "@id": "http://localhost:55001/plone/@relations?source=/document&relation=comprisesComponentPart",
    "relations": {
        "comprisesComponentPart": {
            "items": [
                {
                    "source": {
                        "@id": "http://localhost:55001/plone/document",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000001",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 1",
                        "type_title": "Page"
                    },
                    "target": {
                        "@id": "http://localhost:55001/plone/document-2",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000002",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 2",
                        "type_title": "Page"
                    }
                },
                {
                    "source": {
                        "@id": "http://localhost:55001/plone/document",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000001",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 1",
                        "type_title": "Page"
                    },
                    "target": {
                        "@id": "http://localhost:55001/plone/document-3",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000003",
                        "description": "",
                        "review_state": "private",
                        "title": "Test document 3",
                        "type_title": "Page"
                    }
                }
            ],
            "items_total": 2,
            "readonly": false,
            "staticCatalogVocabularyQuery": null
        }
    }
}

Query relations to a target:

http

GET /plone/@relations?target=/document HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET 'http://nohost/plone/@relations?target=/document' -H "Accept: application/json" --user admin:secret

httpie

http 'http://nohost/plone/@relations?target=/document' Accept:application/json -a admin:secret

python-requests

requests.get('http://nohost/plone/@relations?target=/document', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
HTTP/1.1 200 OK
Content-Type: application/json

{
    "@id": "http://localhost:55001/plone/@relations?target=/document",
    "relations": {
        "relatedItems": {
            "items": [
                {
                    "source": {
                        "@id": "http://localhost:55001/plone/document-2",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000002",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 2",
                        "type_title": "Page"
                    },
                    "target": {
                        "@id": "http://localhost:55001/plone/document",
                        "@type": "Document",
                        "UID": "SomeUUID000000000000000000000001",
                        "description": "",
                        "review_state": "published",
                        "title": "Test document 1",
                        "type_title": "Page"
                    }
                }
            ],
            "items_total": 1
        }
    }
}

Refining#

Querying can be further refined by applying the query_target search parameter to restrict the source or target to either contain a search string or be located under a path.

Search string example:

/@relations?relation=comprisesComponentPart&query_target=wheel

Path example:

/@relations?relation=comprisesComponentPart&query_target=/inside/garden

Limit the results#

Limit the number of results by max to, for example, at most 100 results:

/@relations?relation=comprisesComponentPart&source=/documents/doc-1&max=100

Only broken relations#

Retrieve items with broken relations by querying with onlyBroken:

/@relations?onlyBroken=true

This returns a JSON object, for example:

{
  "@id": "http://localhost:55001/plone/@relations?onlyBroken=true",
  "relations": {
    "relatedItems": {
      "items": [
        "http://localhost:55001/plone/document-2",
      ],
      "items_total": 1
    }
  }
}

Creating relations#

You can create relations by providing a list of the source, target, and name of the relation. The source and target must be either a UID or path.

If the relation is based on a RelationChoice or RelationList field of the source object, the value of the field is updated accordingly.

Create a relation by path:

http

POST /plone/@relations HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json

{
    "items": [
        {
            "relation": "relatedItems",
            "source": "/document-3",
            "target": "/document"
        },
        {
            "relation": "relatedItems",
            "source": "/document-3",
            "target": "/document-2"
        }
    ]
}

curl

curl -i -X POST http://nohost/plone/@relations -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"items": [{"relation": "relatedItems", "source": "/document-3", "target": "/document"}, {"relation": "relatedItems", "source": "/document-3", "target": "/document-2"}]}' --user admin:secret

httpie

echo '{
  "items": [
    {
      "relation": "relatedItems",
      "source": "/document-3",
      "target": "/document"
    },
    {
      "relation": "relatedItems",
      "source": "/document-3",
      "target": "/document-2"
    }
  ]
}' | http POST http://nohost/plone/@relations Accept:application/json Content-Type:application/json -a admin:secret

python-requests

requests.post('http://nohost/plone/@relations', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'items': [{'relation': 'relatedItems', 'source': '/document-3', 'target': '/document'}, {'relation': 'relatedItems', 'source': '/document-3', 'target': '/document-2'}]}, auth=('admin', 'secret'))
HTTP/1.1 204 No Content

Create a relation by UID:

http

POST /plone/@relations HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json

{
    "items": [
        {
            "relation": "comprisesComponentPart",
            "source": "SomeUUID000000000000000000000001",
            "target": "SomeUUID000000000000000000000002"
        },
        {
            "relation": "comprisesComponentPart",
            "source": "SomeUUID000000000000000000000003",
            "target": "SomeUUID000000000000000000000002"
        }
    ]
}

curl

curl -i -X POST http://nohost/plone/@relations -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"items": [{"relation": "comprisesComponentPart", "source": "SomeUUID000000000000000000000001", "target": "SomeUUID000000000000000000000002"}, {"relation": "comprisesComponentPart", "source": "SomeUUID000000000000000000000003", "target": "SomeUUID000000000000000000000002"}]}' --user admin:secret

httpie

echo '{
  "items": [
    {
      "relation": "comprisesComponentPart",
      "source": "SomeUUID000000000000000000000001",
      "target": "SomeUUID000000000000000000000002"
    },
    {
      "relation": "comprisesComponentPart",
      "source": "SomeUUID000000000000000000000003",
      "target": "SomeUUID000000000000000000000002"
    }
  ]
}' | http POST http://nohost/plone/@relations Accept:application/json Content-Type:application/json -a admin:secret

python-requests

requests.post('http://nohost/plone/@relations', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'items': [{'relation': 'comprisesComponentPart', 'source': 'SomeUUID000000000000000000000001', 'target': 'SomeUUID000000000000000000000002'}, {'relation': 'comprisesComponentPart', 'source': 'SomeUUID000000000000000000000003', 'target': 'SomeUUID000000000000000000000002'}]}, auth=('admin', 'secret'))
HTTP/1.1 204 No Content

If either the source or target do not exist, then an attempt to create a relation will fail, and will return a 422 Unprocessable Entity response.

http

POST /plone/@relations HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json

{
    "items": [
        {
            "relation": "comprisesComponentPart",
            "source": "/document",
            "target": "/document-does-not-exist"
        }
    ]
}

curl

curl -i -X POST http://nohost/plone/@relations -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"items": [{"relation": "comprisesComponentPart", "source": "/document", "target": "/document-does-not-exist"}]}' --user admin:secret

httpie

echo '{
  "items": [
    {
      "relation": "comprisesComponentPart",
      "source": "/document",
      "target": "/document-does-not-exist"
    }
  ]
}' | http POST http://nohost/plone/@relations Accept:application/json Content-Type:application/json -a admin:secret

python-requests

requests.post('http://nohost/plone/@relations', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'items': [{'relation': 'comprisesComponentPart', 'source': '/document', 'target': '/document-does-not-exist'}]}, auth=('admin', 'secret'))
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
    "error": {
        "failed": [
            [
                {
                    "relation": "comprisesComponentPart",
                    "source": "/document",
                    "target": "/document-does-not-exist"
                },
                "Failed on creating a relation. Target not found."
            ]
        ],
        "message": "Failed on creating relations",
        "type": "Unprocessable Content"
    }
}

Deleting relations#

You can delete relations by relation name, source object, target object, or a combination of these. You can also delete relations by providing a list of relations.

If a deleted relation is based on a RelationChoice or RelationList field, the value of the field is removed or updated accordingly on the source object.

Delete a list of relations#

You can delete relations by either UID or path.

http

DELETE /plone/@relations HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json

{
    "items": [
        {
            "relation": "comprisesComponentPart",
            "source": "/document",
            "target": "/document-2"
        },
        {
            "relation": "comprisesComponentPart",
            "source": "SomeUUID000000000000000000000001",
            "target": "SomeUUID000000000000000000000003"
        }
    ]
}

curl

curl -i -X DELETE http://nohost/plone/@relations -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"items": [{"relation": "comprisesComponentPart", "source": "/document", "target": "/document-2"}, {"relation": "comprisesComponentPart", "source": "SomeUUID000000000000000000000001", "target": "SomeUUID000000000000000000000003"}]}' --user admin:secret

httpie

echo '{
  "items": [
    {
      "relation": "comprisesComponentPart",
      "source": "/document",
      "target": "/document-2"
    },
    {
      "relation": "comprisesComponentPart",
      "source": "SomeUUID000000000000000000000001",
      "target": "SomeUUID000000000000000000000003"
    }
  ]
}' | http DELETE http://nohost/plone/@relations Accept:application/json Content-Type:application/json -a admin:secret

python-requests

requests.delete('http://nohost/plone/@relations', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'items': [{'relation': 'comprisesComponentPart', 'source': '/document', 'target': '/document-2'}, {'relation': 'comprisesComponentPart', 'source': 'SomeUUID000000000000000000000001', 'target': 'SomeUUID000000000000000000000003'}]}, auth=('admin', 'secret'))
HTTP/1.1 204 No Content

If either the source or target do not exist, then an attempt to delete a relation will fail, and will return a 422 Unprocessable Entity response.

http

DELETE /plone/@relations HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json

{
    "items": [
        {
            "relation": "comprisesComponentPart",
            "source": "/document",
            "target": "/dont-know-this-doc"
        },
        {
            "relation": "comprisesComponentPart",
            "source": "/doc-does-not-exist",
            "target": "/document"
        }
    ]
}

curl

curl -i -X DELETE http://nohost/plone/@relations -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"items": [{"relation": "comprisesComponentPart", "source": "/document", "target": "/dont-know-this-doc"}, {"relation": "comprisesComponentPart", "source": "/doc-does-not-exist", "target": "/document"}]}' --user admin:secret

httpie

echo '{
  "items": [
    {
      "relation": "comprisesComponentPart",
      "source": "/document",
      "target": "/dont-know-this-doc"
    },
    {
      "relation": "comprisesComponentPart",
      "source": "/doc-does-not-exist",
      "target": "/document"
    }
  ]
}' | http DELETE http://nohost/plone/@relations Accept:application/json Content-Type:application/json -a admin:secret

python-requests

requests.delete('http://nohost/plone/@relations', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'items': [{'relation': 'comprisesComponentPart', 'source': '/document', 'target': '/dont-know-this-doc'}, {'relation': 'comprisesComponentPart', 'source': '/doc-does-not-exist', 'target': '/document'}]}, auth=('admin', 'secret'))
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
    "error": {
        "failed": [
            [
                {
                    "relation": "comprisesComponentPart",
                    "source": "/document",
                    "target": "/dont-know-this-doc"
                },
                "Failed on deleting a relation. Target not found."
            ],
            [
                {
                    "relation": "comprisesComponentPart",
                    "source": "/doc-does-not-exist",
                    "target": "/document"
                },
                "Failed on deleting a relation. Source not found."
            ]
        ],
        "message": "Failed on deleting relations",
        "type": "Unprocessable Content"
    }
}

Delete relations by relation name#

http

DELETE /plone/@relations HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json

{
    "relation": "relatedItems"
}

curl

curl -i -X DELETE http://nohost/plone/@relations -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"relation": "relatedItems"}' --user admin:secret

httpie

echo '{
  "relation": "relatedItems"
}' | http DELETE http://nohost/plone/@relations Accept:application/json Content-Type:application/json -a admin:secret

python-requests

requests.delete('http://nohost/plone/@relations', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'relation': 'relatedItems'}, auth=('admin', 'secret'))
HTTP/1.1 204 No Content

Delete relations by source#

You can delete relations by either source UID or path.

The following example shows how to delete a relation by source path.

http

DELETE /plone/@relations HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json

{
    "source": "/document"
}

curl

curl -i -X DELETE http://nohost/plone/@relations -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"source": "/document"}' --user admin:secret

httpie

echo '{
  "source": "/document"
}' | http DELETE http://nohost/plone/@relations Accept:application/json Content-Type:application/json -a admin:secret

python-requests

requests.delete('http://nohost/plone/@relations', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'source': '/document'}, auth=('admin', 'secret'))
HTTP/1.1 204 No Content

Delete relations by target#

You can delete relations by either target UID or path.

The following example shows how to delete a relation by target path.

http

DELETE /plone/@relations HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json

{
    "target": "/document"
}

curl

curl -i -X DELETE http://nohost/plone/@relations -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"target": "/document"}' --user admin:secret

httpie

echo '{
  "target": "/document"
}' | http DELETE http://nohost/plone/@relations Accept:application/json Content-Type:application/json -a admin:secret

python-requests

requests.delete('http://nohost/plone/@relations', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'target': '/document'}, auth=('admin', 'secret'))
HTTP/1.1 204 No Content

Delete relations by a combination of source, target, and relation name#

You can delete relations by a combination of either any two of their relation name, source, and target, or a combination of all three. In the following example, you would delete a relation by its relation name and target.

http

DELETE /plone/@relations HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json

{
    "relation": "relatedItems",
    "target": "/document"
}

curl

curl -i -X DELETE http://nohost/plone/@relations -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"relation": "relatedItems", "target": "/document"}' --user admin:secret

httpie

echo '{
  "relation": "relatedItems",
  "target": "/document"
}' | http DELETE http://nohost/plone/@relations Accept:application/json Content-Type:application/json -a admin:secret

python-requests

requests.delete('http://nohost/plone/@relations', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'relation': 'relatedItems', 'target': '/document'}, auth=('admin', 'secret'))
HTTP/1.1 204 No Content

Fix relations#

Broken relations can be fixed by releasing and re-indexing them. A successfully fixed relation will return a 204 No Content response.

http

POST /plone/@relations/rebuild HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X POST http://nohost/plone/@relations/rebuild -H "Accept: application/json" --user admin:secret

httpie

http POST http://nohost/plone/@relations/rebuild Accept:application/json -a admin:secret

python-requests

requests.post('http://nohost/plone/@relations/rebuild', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))

In rare cases, you may need to flush the intIds. You can rebuild relations by flushing the intIds with the following HTTP POST request.

Warning

If your code relies on intIds, you should take caution and think carefully before you flush them.

http

POST /plone/@relations/rebuild HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json

{
    "flush": 1
}

curl

curl -i -X POST http://nohost/plone/@relations/rebuild -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"flush": 1}' --user admin:secret

httpie

echo '{
  "flush": 1
}' | http POST http://nohost/plone/@relations/rebuild Accept:application/json Content-Type:application/json -a admin:secret

python-requests

requests.post('http://nohost/plone/@relations/rebuild', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'flush': 1}, auth=('admin', 'secret'))