The word Daftar comes from Farsi (دفتر), which means notebook. This website is implemented with the Django framework and allows you to post in Markdown format and also has a commenting service inside!
- Python 3.10+
- Poetry
- PostgreSQL for production (SQLite works for local development/tests)
First, install the dependencies:
poetry installConfigure the database and adapt the environment variables to it. Look at the example here, then copy it and fill in your values:
cp daftar/.env.example .envApply migrations (they are committed, no need to run makemigrations):
poetry run python manage.py migrateFirst, create a dedicated role and database for the project (run this once,
as the postgres superuser; psql -l should not yet contain portfolio_db):
sudo -u postgres psqlCREATE ROLE daftar WITH LOGIN PASSWORD 'a-strong-password';
CREATE DATABASE portfolio_db OWNER daftar;
\qThen point daftar/.env at them (and never commit the real .env):
DB_ENGINE=postgresql
DB_NAME=portfolio_db
DB_USER=daftar
DB_PASSWORD=a-strong-password
DB_HOST=127.0.0.1
DB_PORT=5432Verify the connection and apply the migrations:
PGPASSWORD='a-strong-password' psql -h 127.0.0.1 -U daftar -d portfolio_db -c 'select 1;'
poetry run python manage.py migrateIf migrate fails with permission denied for schema public:
First, see exactly which role/database Django is using (this command also probes the schema permissions and prints the fix for your exact values):
poetry run python manage.py dbcheckPostgreSQL 15+ no longer grants CREATE on the public schema to everyone;
only the schema/database owner can create tables. Run this complete, idempotent
setup once as the postgres superuser (note: privilege commands must run
while connected to portfolio_db, not the postgres database):
# 1) Make daftar the database owner (runs at cluster level)
sudo -u postgres psql -d postgres -c "ALTER DATABASE portfolio_db OWNER TO daftar;"
# 2) Make daftar the owner of the schema itself ...
sudo -u postgres psql -d portfolio_db -c "ALTER SCHEMA public OWNER TO daftar;"
# ... and grant explicitly anyway (covers every cluster layout)
sudo -u postgres psql -d portfolio_db -c "GRANT USAGE, CREATE ON SCHEMA public TO daftar;"Verify that the role can really create tables as the app user:
psql -h 127.0.0.1 -U daftar -d portfolio_db \
-c "SELECT current_user, has_schema_privilege(current_user, 'public', 'CREATE');"
# Expected: daftar | t (true)If it prints f, check the schema owner/ACL and the .env values:
sudo -u postgres psql -d portfolio_db -c '\dn+ public'
grep -E '^DB_' daftar/.envThen apply the migrations:
poetry run python manage.py migrateNotes:
- On Arch, PostgreSQL does not start automatically;
sudo systemctl start postgresql(andenableit if you want it on boot). Check withpg_isready. - If you prefer the existing
rootrole, it must also work forlocalhost/127.0.0.1connections:ALTER ROLE root WITH LOGIN PASSWORD '...';thenCREATE DATABASE portfolio_db OWNER root;and use those credentials in.env. localhostcan resolve to::1first (as in the error you saw);127.0.0.1is unambiguous. The database must exist — Postgres reportsFATAL: database "..." does not existbefore Django can create anything.
Run the test suite (SQLite keeps it fast):
DB_ENGINE=sqlite poetry run python manage.py testRun it in development:
poetry run python manage.py createsuperuser # only needed once (a superuser)
poetry run python manage.py runserver --insecureThe superuser credentials are what you log in with at /admin/ and what
unlocks the post/comment editing features.
This happens when Poetry is configured to install into your global/system
Python (virtualenvs.create = false) and that environment's site-packages
is not writable (for example, a system-wide Python installed with sudo
under /usr/local, as is common with make altinstall). Poetry wants to use
its own virtual environment, which also keeps dependencies isolated from
your system packages.
Diagnose it:
poetry config virtualenvs.create # should print true
poetry config --list | grep virtualenvs
poetry env info # "Path" should point into ~/.cache/pypoetry/...Fix it by letting Poetry manage the virtualenv again:
poetry config virtualenvs.create true
poetry env remove --all # clear the broken environment first
poetry install
poetry run python manage.py checkIf you deliberately keep virtualenvs.create = false, create and activate a
project virtualenv first so Poetry has a writable destination:
python3 -m venv .venv
source .venv/bin/activate
poetry installCheck the deployment readiness:
# Start from daftar/.env.example and set DEBUG=0, a real secret key and
# ALLOWED_HOSTS before running:
poetry run python manage.py check --deployNote: Only superusers can update posts and comments through the website...
The project follows Django's deployment checklist. The defaults are hardened
for production (DEBUG and SECURE_SSL_REDIRECT derive from the environment),
a Content-Security-Policy is enforced with per-request nonces, comment content
is sanitized with nh3, comments are rate
limited per IP with a honeypot trap, and the test suite covers authentication,
authorization, input validation, and XSS scenarios.
Continuous integration runs:
rufflinting and formatting checks- the Django test suite
- a production
manage.py check --deploy - an OSV-Scanner audit of
poetry.lock(also watch the GitHub Security tab; [Dependabot] (https://docs.github.com/en/code-security/dependabot) keeps the dependencies updated weekly)
Heads-up for existing deployments:
db.jsonwas a dump of the live database (users, sessions, admin logs) and has been removed from the repository. If you ever committed it, also purge it from Git history (git filter-repo --path db.json --invert-paths/ BFG) and rotateDJANGO_SECRET_KEYand the admin password, because the database dump contained session data that can be forged with a leaked secret key.
This project is licensed under the MIT license found in the LICENSE file in the root directory of this repository.