How-To Guides

Load Vocabularies

How to load and update controlled vocabularies from the spec

This guide explains how to load controlled vocabularies from the ZineCore2 specification into your database.

Prerequisites

  • ✅ ZineCore2 server installed
  • ✅ PostgreSQL database created and migrated
  • ✅ Spec submodule initialized (git submodule update --init)
  • ✅ Virtual environment activated

Understanding Vocabularies

ZineCore2 uses 8 controlled vocabularies:

VocabularyUsed ByFile
SubjectsZinesspec/vocabularies/generated/django/subjects.json
GenresZinesspec/vocabularies/generated/django/genres.json
Agent KindsAgentsspec/vocabularies/generated/django/agent-kinds.json
Agent RolesAgentsspec/vocabularies/generated/django/agent-roles.json
Repository KindsRepositoriesspec/vocabularies/generated/django/repository-kinds.json
Access StatusHoldingsspec/vocabularies/generated/django/access-status.json
Rights StatusZinesspec/vocabularies/generated/django/rights-status.json
FormatsZinesspec/vocabularies/generated/django/formats.json

Location: All vocabulary fixtures are in spec/vocabularies/generated/django/


Load All Vocabularies

Step 1: Ensure Spec is Up to Date

cd /path/to/server
git submodule update --remote spec

This pulls the latest vocabulary definitions.

Step 2: Run Load Command

cd backend
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py load_vocabularies

Expected output:

Loading vocabularies from spec...
✓ Loaded 45 subjects
✓ Loaded 12 genres
✓ Loaded 3 agent kinds
✓ Loaded 8 agent roles
✓ Loaded 7 repository kinds
✓ Loaded 5 access status codes
✓ Loaded 6 rights statements
✓ Loaded 10 formats
Successfully loaded all vocabularies!

Step 3: Verify

Check that vocabularies were loaded:

# Via Django shell
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py shell

>>> from catalog.models import Subject, Genre
>>> Subject.objects.count()
45
>>> Genre.objects.count()
12

Or via API:

curl http://localhost:8000/api/vocabularies/subjects/ | jq '.count'
# Should return: 45

Load Individual Vocabulary

To load only a specific vocabulary:

Subjects

cd backend
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py loaddata ../spec/vocabularies/generated/django/subjects.json

Genres

DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py loaddata ../spec/vocabularies/generated/django/genres.json

Agent Kinds

DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py loaddata ../spec/vocabularies/generated/django/agent-kinds.json

Update Vocabularies

When vocabularies change in the spec:

Step 1: Pull Latest Spec

cd /path/to/server
git submodule update --remote spec

Step 2: Reload Vocabularies

cd backend
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py load_vocabularies

Behavior:

  • Existing terms are updated if changed
  • New terms are added
  • Removed terms are deleted (if not referenced by any records)

Step 3: Verify Changes

# Check via API
curl http://localhost:8000/api/vocabularies/subjects/

# Or via Django shell
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py shell

>>> from catalog.models import Subject
>>> Subject.objects.filter(code='new-subject-code').first()

Manual Vocabulary Management

Add Custom Term

If you need a custom vocabulary term not in the spec:

DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py shell
from catalog.models import Subject

# Create custom subject
Subject.objects.create(
    code='local-custom-subject',
    label='Local Custom Subject',
    definition='Custom subject term for local use',
    uri='https://example.org/subjects#local-custom-subject'
)

Warning: Custom terms may be overwritten if they conflict with spec updates.

Delete Unused Term

from catalog.models import Genre

# Delete genre (only if not referenced by any zines)
Genre.objects.filter(code='obsolete-genre').delete()

Note: Django will prevent deletion if the term is referenced by any records.


Vocabulary Fixture Format

Vocabulary fixtures use Django's JSON fixture format:

[
  {
    "model": "catalog.subject",
    "fields": {
      "code": "feminism",
      "label": "Feminism",
      "definition": "Social, political, and economic equality of the sexes.",
      "uri": "https://zinecore.org/v2/subjects#feminism"
    }
  },
  {
    "model": "catalog.subject",
    "fields": {
      "code": "punk",
      "label": "Punk",
      "definition": "Punk subculture and music.",
      "uri": "https://zinecore.org/v2/subjects#punk"
    }
  }
]

Fields:

  • code — Unique identifier (used in API)
  • label — Display name
  • definition — Term definition
  • uri — Full URI for the term

Troubleshooting

"No such file or directory: spec/vocabularies/..."

Cause: Spec submodule not initialized

Solution:

cd /path/to/server
git submodule update --init

"IntegrityError: duplicate key value violates unique constraint"

Cause: Vocabulary term already exists

Solution: The load_vocabularies command should handle this. If using loaddata directly, delete existing terms first:

DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py shell
from catalog.models import Subject
Subject.objects.all().delete()

Then reload.

"Cannot delete vocabulary term: still referenced by records"

Cause: Vocabulary term is used by existing records

Solution:

  1. Find records using the term:
from catalog.models import Zine, Subject

subject = Subject.objects.get(code='obsolete-term')
zines_using_term = Zine.objects.filter(subject__contains=[subject.code])
print(f"Used by {zines_using_term.count()} zines")
  1. Update those records to use a different term
  2. Then delete the vocabulary term

"Command 'load_vocabularies' not found"

Cause: Management command not available

Solution: Ensure you're in the backend/ directory and using the correct settings module:

cd backend
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py load_vocabularies

Vocabulary Workflow

For Spec Maintainers

If you maintain the spec and need to update vocabularies:

Step 1: Edit canonical source

cd spec
# Edit spec/vocabularies/canonical/subjects.json

Step 2: Rebuild generated files

cd spec
node scripts/build-vocabularies.js

This regenerates all formats (CSV, SKOS, JSON-LD, Django fixtures).

Step 3: Commit changes

git add vocabularies/canonical/ vocabularies/generated/
git commit -m "Update subjects vocabulary"
git push

Step 4: Update server

cd ../server
git submodule update --remote spec
cd backend
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py load_vocabularies

For Server Operators

If you only operate a server and don't maintain the spec:

Step 1: Pull latest spec

cd /path/to/server
git pull
git submodule update --remote spec

Step 2: Reload vocabularies

cd backend
DJANGO_SETTINGS_MODULE=zinecore.settings.development \
  ../.venv/bin/python manage.py load_vocabularies

Production Considerations

Before Production Deployment

  1. Load vocabularies before loading any data
  2. Test thoroughly to ensure all required terms exist
  3. Backup database before updating vocabularies

Updating Vocabularies in Production

# Backup first
pg_dump -U zinecore2 -d zinecore2_prod > backup-$(date +%Y%m%d).sql

# Update spec
git submodule update --remote spec

# Reload vocabularies
cd backend
DJANGO_SETTINGS_MODULE=zinecore.settings.production \
  .venv/bin/python manage.py load_vocabularies

# Verify
DJANGO_SETTINGS_MODULE=zinecore.settings.production \
  .venv/bin/python manage.py shell
>>> from catalog.models import Subject
>>> Subject.objects.count()

Monitoring

After updating vocabularies, check:

  1. Record counts — Ensure no unexpected changes
  2. API responses — Test vocabulary endpoints
  3. Application logs — Check for errors

Best Practices

DO:

  • ✅ Always update spec submodule before loading vocabularies
  • ✅ Use load_vocabularies command (handles updates gracefully)
  • ✅ Backup database before major vocabulary changes
  • ✅ Test vocabulary updates in development first
  • ✅ Document any custom vocabulary terms you add

DON'T:

  • ❌ Manually edit vocabulary records in the database
  • ❌ Delete vocabulary terms that might be referenced
  • ❌ Skip vocabulary loading during initial setup
  • ❌ Use inconsistent vocabulary codes across environments

Next Steps

Vocabularies loaded! Continue to Bulk Import to load zine data.
Copyright ©2026 ZineCore2 Contributors,