autor models.py 


from pyexpat import model
from django.db import models
# managers
from .managers import AutorManager

class Persona(models.Model):
    nombre = models.CharField(
        max_length=50
    )
    apellidos = models.CharField(
        max_length=50
    )
    nacionalidad = models.CharField(
        max_length=20
    )
    edad = models.PositiveIntegerField()

    def __str__(self):
        return str(self.id)+'-'+ self.nombre + '-'+ self.apellidos

    class Meta:
        abstract=True
        

class Autor(Persona):
    seudonimo = models.CharField(
        'seudonimo',
        max_length=50,
        blank= True
        )
    objects=AutorManager()

lector models.py

from tabnanny import verbose
from django.db import models
#from locasl apps
from django.db.models.signals import post_delete

from applications.libro.models import Libro
from applications.autor.models import Persona
# from managers

from .managers import PrestamoManager
from .singals import update_libro_stok

# Create your models here.
class Lector(Persona):

    class Meta:
        verbose_name='Lector'
        verbose_name_plural='Lectores'

class Prestamo(models.Model):
    lector = models.ForeignKey(
        Lector, 
        on_delete=models.CASCADE
    )
    libro = models.ForeignKey(
        Libro, 
        on_delete=models.CASCADE,
        related_name='libro_prestamo'
    )
    fecha_prestamo = models.DateField()
    fecha_devolucion = models.DateField(
        blank=True,
        null=True
    )
    devuelto = models.BooleanField()
    
    objects = PrestamoManager()

    def save(self,*args,**kwargs):
        super(Prestamo,self).save(*args,**kwargs)

        print('===========')
        self.libro.stok=self.libro.stok - 1
        self.libro.save()

    def __str__(self):
        return self.libro.titulo

# def update_libro_stok(sender,instance,**kwargs):
#     #actualizamos el stok si se elimina  un prestamo
#     instance.libro.stok = instance.libro.stok +1
#     instance.libro.save()
post_delete.connect(update_libro_stok,sender=Prestamo)

libro models.py

from pickletools import optimize
from django.db import models
from django.db.models.signals import post_save

#apps de tercero

from PIL import Image

from applications.autor.models import Autor

from .managers import LibroManager,CategoriaManager
# Create your models here.


class Categoria(models.Model):
    nombre = models.CharField(max_length=30)

    objects=CategoriaManager()

    def __str__(self):
        return str(self.id) + ' - '+ self.nombre


class Libro(models.Model):
    categoria = models.ForeignKey(
        Categoria,
        on_delete=models.CASCADE,
        related_name='categoria_libro'
    )
    autores = models.ManyToManyField(Autor)
    titulo = models.CharField(
        max_length=50
    )
    fecha = models.DateField('Fecha de Lanzamiento')
    portada = models.ImageField(upload_to='portada')
    visitas = models.PositiveIntegerField()
    stok=models.PositiveIntegerField(default=0)

    objects = LibroManager()

    class Meta:
        verbose_name='Libro'
        verbose_name_plural='Libros'
        ordering=['titulo','fecha']


    def __str__(self):
        return str(self.id) + '-'+ self.titulo

    def listar_libros_categoria(self,categoria):

        return self.filter(
            categoria__id=categoria
        ).order_by('titulo')

def optimize_image(sender,instance,**kwargs):
    print("========")
    print(instance)
    if instance.portada:
        portada= Image.open(instance.portada.path)
        portada.save(instance.portada.path,quality=20,optimize=True)

post_save.connect(optimize_image,sender=Libro)

home models.py


from enum import unique
from django.db import models

# Create your models here.
class Persona(models.Model):

    full_name = models.CharField('nombres', max_length=50)
    pais = models.CharField('Pais', max_length=30)
    pasaporte = models.CharField('Pasaporte', max_length=50)
    edad = models.IntegerField()
    apelativo = models.CharField('Apelativo', max_length=10)

    class Meta:

        verbose_name = 'Persona'
        verbose_name_plural = 'Personas'
        db_table='persona'
        unique_together=['pais','apelativo']
        constraints=[
            models.CheckConstraint(check=models.Q(edad__gte=18), name='edad_mayor_18')
        ]
        abstract = True

    def __str__(self):
        return self.full_name

class Empleados(Persona):
    empleo = models.CharField('Empleo', max_length=50)
    

# class Cliente(Persona):
#     email = models.CharField('email', max_length=50)
    

 

base.py 


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.postgres',
    #local apps
    'applications.autor',
    'applications.libro',
    'applications.lector',
]

urls.py del principal

"""biblioteca URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,re_path,include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('',include('applications.autor.urls')),
    re_path('',include('applications.libro.urls')),
    re_path('',include('applications.lector.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

hacer las migraciones