mkdir django-postgresql-crud
cd django-postgresql-crud

creacion de entorno virtual:

virtualenv venv
source ./venv/bin/activate

creacion de proyecto en Django:

pip install django
django-admin startproject djangocrud .
python manage.py runserver

creacion de una aplicacion

python manage.py startapp tasks

luego añadelo a INSTALLED_APPS en settings.py

INSTALLED_APPS = [
    'tasks',
    'django.contrib.admin',
    ...
]

Configurando PostgreSQL

primero crea una base de datos en PostgreSQL, llamada taskdb:

CREATE DATABASE taskdb;

en settings.py:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'tasksdb', 'USER': 'postgres', 'PASSWORD': 'password', 'HOST': 'localhost', 'PORT': '5432', } }

creando Task model

Django tiene un ORM incluido, lo que quiere decir es que puede convertir las clases a tablas, para esto vamos a tasks/models.py

from django.db import models

# Create your models here.
class Task(models.Model):
  title = models.TextField()

tambien es posible crear las migraciones de forma individual, por ejemplo:

python manage.py makemigrations
python manage.py migrate
python manage.py makemigrations tasks

Esto creara una carpeta llamada migrations, y adentro un archivo 001. Luego puedes ejecutar esta

python manage.py sqlmigrate tasks 0001

Si revisas tu base de datos, veras multiples tablas creadas.

Añadiendo URLs

Primero creemos un template en tasks/templates/list_tasks.html\

list tasks

luego una vista en tasks/views.py

from django.shortcuts import render

# Create your views here.
def list_tasks(request):
    return render(request, 'list_tasks.html')

luego creemos un archivo tasks/urls.py

from django.urls import path
from . import views

urlpatterns = [
  path('', views.list_tasks)
]

ahora vamos a añadir las URLs que le pertenecen a tasks en djangocrud/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('tasks/', include('tasks.urls')),
]

static files

dentro de tasks/static

crea un archivo main.css

y luego puedes importarlo usando:

{% load static %}

<h1>List tasks</h1>

crear tarea

en list_tasks.html

<form action="/tasks/new/" method="POST">
  {% csrf_token %}
  <input type="text" name="title" placeholder="Write a title">
  <button>save</button>
</form>

otra forma de definir el action, es usando el nombre de la url:

<form action="{% url 'create_task' %}" method="POST">
...
</form>

esto es util si luego quieres cambiar la url, no tendras que cambiarla en todos lados donde se use, ya que el nombre sigue siendo el mismo. asi que es la forma recomendada en Django.

en tasks/views.py

...
def create_task(request):
  title = Task(title=request.POST['title'])
  title.save()
  return redirect('/tasks/')

en tasks/urls.py

urlpatterns = [ path('', views.list_tasks), path('new/', views.create_task), ]

Si revisas tu base de datos veras un nuevo dato creado.

Mostrar tareas creadas

def list_tasks(request): tasks = Task.objects.all() return render(request, "list_tasks.html", {"tasks": tasks})

en list_tasks.html:

{% for task in tasks %}
  <div>
    {{ task.title }}
    <form action="/tasks/"></form>
  </div>
{% empty %}
  <h1>No tasks yet</h1>
{% endfor %}

delete tasks

def delete_task(request, task_id): task = Task.objects.get(id=task_id) task.delete() return redirect("/tasks/")

en tasks/urls.py:

from django.urls import path from . import views

urlpatterns = [ ... path('delete_task/int:task_id/', views.delete_task, name='delete_task'), ]

en list_tasks.html

{% for task in tasks %}
  <div>
    {{ task.title }}
    <form action="{% url 'delete_task' task.id %}" method="POST">
      <button>Delete</button>
    </form>
  </div>
{% empty %}
...
{% endfor %}