Skip to main content

A RDF library for Django models

Project description

Django RDF

Maintenance

GitHub license

forthebadge made-with-python

PyPI - Downloads

PyPI - Version

djangordf is a Django library for managing RDF data with a declarative model layer. Domain classes are written like Django models but persist as triples in a SPARQL 1.1 triple store, with built-in SKOS conventions, language-tagged literals, and a lazy queryset that mirrors Django's manager API.

Full reference documentation: https://djangordf.readthedocs.io/.

Features

  • RDFModel — declarative base class with class_iri, namespace, and graph_iri configured through a Meta inner class. Defaults to skos:Concept and uses the namespace and graph IRIs from Django settings.
  • Property typesDataProperty for typed literals, LangStringProperty for rdf:langString (using the LangString dataclass), ObjectProperty for instance-to-instance links (with lazy "self" and string-name target resolution), and URIProperty for raw IRIs. Each supports many=True/False cardinality.
  • SKOS defaults — properties named pref_label, alt_label, broader, narrower, etc. resolve to their SKOS predicates automatically; no explicit predicate= needed for the conventions.
  • RDFManager + lazy RDFQuerySet — Django-style objects.create, objects.get, objects.all, objects.filter. save is idempotent and overwrites stale triples in a single SPARQL update; delete strips every triple for the IRI.
  • Backends — ships an InMemoryBackend (rdflib, good for tests and local development) and a FusekiBackend (SPARQL 1.1 HTTP, works against Apache Jena Fuseki, GraphDB, Blazegraph, Stardog).
  • NamespaceRegistry — register prefixes through DJANGORDF_NAMESPACES and resolve CURIEs like "skos:Concept" into full URIRef objects.
  • Legacy export_model_to_rdf — the original Django-model-to-RDF exporter from earlier releases still works unchanged.

Installation

pip install djangordf

Add the app to INSTALLED_APPS and configure a backend:

# settings.py
INSTALLED_APPS = [
    # ...
    "djangordf",
]

DJANGORDF_BACKEND = {
    "class": "djangordf.backends.memory.InMemoryBackend",
}

DJANGORDF_DEFAULT_NAMESPACE = "http://example.org/data/"
DJANGORDF_DEFAULT_GRAPH = "http://example.org/graph/default"

DJANGORDF_NAMESPACES = {
    "ex": "http://example.org/vocab/",
}

Talking to a real triple store

Swap in the Fuseki backend (or any SPARQL 1.1 endpoint):

DJANGORDF_BACKEND = {
    "class": "djangordf.backends.fuseki.FusekiBackend",
    "endpoint": "http://localhost:3030/judaicalink",
    # optional:
    "user": "admin",
    "password": "secret",
}

The repository ships a docker-compose.yml that boots a local Fuseki for development; opt-in integration tests behind the @pytest.mark.fuseki marker exercise the HTTP path end-to-end.

Usage

Define a model:

from djangordf import (
    RDFModel,
    LangStringProperty,
    ObjectProperty,
)
from djangordf.namespaces import LangString


class Term(RDFModel):
    pref_label = LangStringProperty(many=True)
    alt_label = LangStringProperty(many=True)
    broader = ObjectProperty("self", many=True)

No class Meta, no predicate= arguments: Term defaults to skos:Concept, and pref_label / alt_label / broader resolve to their SKOS predicates through the convention map. Mint, query, link:

buch = Term.objects.create(
    pref_label=[LangString("Buch", "de"), LangString("Book", "en")],
)
roman = Term.objects.create(
    pref_label=[LangString("Roman", "de")],
    broader=[buch],
)

reloaded = Term.objects.get(roman.iri)
assert reloaded.broader[0].iri == buch.iri
assert any(
    ls.lang == "en" and ls.value == "Book"
    for ls in buch.pref_label
)

save is idempotent — calling it twice does not duplicate triples. Updates overwrite previous values in one SPARQL transaction:

buch.pref_label = [LangString("Buch (überarbeitet)", "de")]
buch.save()

Queries return a lazy RDFQuerySet; the store is only hit on iteration, len, count, or first:

for term in Term.objects.all():
    print(term.iri, term.pref_label)

assert Term.objects.filter(broader=buch).count() == 1

Explicit predicates and CURIE-based class IRIs are also supported:

from rdflib import URIRef
from rdflib.namespace import XSD

from djangordf import DataProperty, URIProperty


class Person(RDFModel):
    name = DataProperty(
        predicate=URIRef("http://xmlns.com/foaf/0.1/name"),
        datatype=XSD.string,
    )
    homepage = URIProperty(
        predicate=URIRef("http://xmlns.com/foaf/0.1/homepage"),
    )

    class Meta:
        class_iri = "foaf:Person"   # resolved via NamespaceRegistry
        namespace = "http://example.org/people/"
        graph_iri = "http://example.org/graph/people"

Walking-skeleton example

A self-contained, runnable end-to-end example lives at examples/walking_skeleton.py. It mirrors the design spec's acceptance script and exits 0 against the default in-memory backend:

python examples/walking_skeleton.py

Legacy Django-to-RDF export

The original export_model_to_rdf(QuerySet, ...) function is still available for one-shot dumps of relational Django data into a Turtle file; see djangordf/functions.py and the existing tests in tests/test_export.py.

Settings reference

Setting Purpose Default
DJANGORDF_BACKEND Triple-store backend config (dict with class plus kwargs) In-memory backend
DJANGORDF_DEFAULT_NAMESPACE Used to mint IRIs when Meta.namespace is silent urn:djangordf:<model>:
DJANGORDF_DEFAULT_GRAPH Used when Meta.graph_iri is silent urn:djangordf:default
DJANGORDF_NAMESPACES prefix -> uri map read into the NamespaceRegistry at app ready {}

License

This project is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

djangordf-0.7.0.tar.gz (41.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

djangordf-0.7.0-py3-none-any.whl (25.4 kB view details)

Uploaded Python 3

File details

Details for the file djangordf-0.7.0.tar.gz.

File metadata

  • Download URL: djangordf-0.7.0.tar.gz
  • Upload date:
  • Size: 41.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for djangordf-0.7.0.tar.gz
Algorithm Hash digest
SHA256 55c0b00be2b523c68f54957e156aab0e5795e2b199af74392c595455eb1b03c2
MD5 6e55f48a66e9d0dd00bfd31c8a6eb749
BLAKE2b-256 1052c1148e241d2bf24acbe9981d8a8c900284a786bff3574bdd1f115e1da193

See more details on using hashes here.

Provenance

The following attestation bundles were made for djangordf-0.7.0.tar.gz:

Publisher: python-publish.yml on judaicalink/djangordf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file djangordf-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: djangordf-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 25.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for djangordf-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a092da23bc76258e00e5bd2a156c236401d7c82d3a27f8a66565cde3f2a541eb
MD5 634ed50fd1d71bd15671b714c31a8b37
BLAKE2b-256 41be3942615967f18eb24bb950f3ba6beca3a6f3b10219e7f851c81f3a39c9f5

See more details on using hashes here.

Provenance

The following attestation bundles were made for djangordf-0.7.0-py3-none-any.whl:

Publisher: python-publish.yml on judaicalink/djangordf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page