Browse Source

Imagen en dos etapas

politica
Celestino Rey 1 year ago
parent
commit
b8a49dab50
14 changed files with 118 additions and 54 deletions
  1. +30
    -6
      Libros/Dockerfile
  2. +1
    -1
      Libros/K8S/Makefile
  3. +1
    -1
      Libros/biblioteca/accounts/urls.py
  4. +3
    -2
      Libros/biblioteca/accounts/views.py
  5. +21
    -21
      Libros/biblioteca/biblioteca/settings.py
  6. +6
    -2
      Libros/biblioteca/biblioteca/urls.py
  7. +15
    -8
      Libros/biblioteca/gestion/admin.py
  8. +14
    -5
      Libros/biblioteca/gestion/forms.py
  9. +1
    -1
      Libros/biblioteca/gestion/managers.py
  10. +4
    -1
      Libros/biblioteca/gestion/models.py
  11. +2
    -1
      Libros/biblioteca/gestion/templatetags/filtros_de_entorno.py
  12. +1
    -1
      Libros/biblioteca/gestion/urls.py
  13. +12
    -2
      Libros/biblioteca/gestion/views.py
  14. +7
    -2
      Libros/requirements.txt

+ 30
- 6
Libros/Dockerfile View File

@ -1,8 +1,9 @@
# syntax=docker/dockerfile:1
##################
# BUILDER #
##################
FROM python:3.11.4-slim-buster
#FROM python:3.9.19-slim-bullseye
FROM python:3.11.4-slim-buster AS builder
# set work directory
WORKDIR /app
@ -12,7 +13,26 @@ ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# install system dependencies
RUN apt-get update && apt-get install -y sqlite3 netcat
RUN apt-get update && \
apt-get install -y --no-install-recommends gcc
# lint
RUN pip install --upgrade pip
RUN pip install flake8==6.0.0
COPY . /app/
RUN flake8 --ignore=E501,F401,E126 .
COPY ./requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt
##################
# FINAL #
##################
FROM python:3.11.4-slim-buster
# create directory for the app user
RUN mkdir -p /app
@ -27,9 +47,13 @@ RUN mkdir -p $APP_HOME
#RUN mkdir -p $APP_HOME/mediafiles
WORKDIR $APP_HOME
# install system dependencies
RUN apt-get update && apt-get install -y sqlite3 netcat
COPY --from=builder /app/wheels /wheels
COPY --from=builder /app/requirements.txt .
RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r /app/requirements.txt
RUN pip install --no-cache /wheels/*
# copy entrypoint.sh
COPY ./entrypoint.sh .


+ 1
- 1
Libros/K8S/Makefile View File

@ -1,5 +1,5 @@
export ARQUITECTURA := $(shell lscpu |grep itectur | tr -d ' '| cut -f2 -d':')
export IMG_VERSION = 1.29
export IMG_VERSION = 1.30
export IMG_NGINX_VERSION = 1.17
# limpia todo


+ 1
- 1
Libros/biblioteca/accounts/urls.py View File

@ -9,4 +9,4 @@ urlpatterns = [
path("signup/", SignUpView.as_view(), name="signup"),
path('login/', auth_views.LoginView.as_view(), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]
]

+ 3
- 2
Libros/biblioteca/accounts/views.py View File

@ -1,11 +1,12 @@
# accounts/views.py
#from django.contrib.auth.forms import UserCreationForm
# from django.contrib.auth.forms import UserCreationForm
from django.urls import reverse_lazy
from django.views.generic import CreateView
from gestion.forms import ReyMotaUserCreationForm
class SignUpView(CreateView):
form_class = ReyMotaUserCreationForm
success_url = reverse_lazy("login")
template_name = "registration/signup.html"
template_name = "registration/signup.html"

+ 21
- 21
Libros/biblioteca/biblioteca/settings.py View File

@ -21,11 +21,11 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
#SECRET_KEY = 'django-insecure-q0bxrr=*ab*b8oa#=+-@_4cu-cp6)c3lz#+!c_%51$*!bnz%4!'
SECRET_KEY = os.environ.get("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
#DEBUG = True
# DEBUG = True
DEBUG = bool(os.environ.get("DEBUG", default=0))
@ -88,8 +88,8 @@ DATABASES = {
}
}
#print("DB:",DATABASES)
#print("BASE_DIR:",BASE_DIR)
# print("DB:",DATABASES)
# print("BASE_DIR:",BASE_DIR)
# Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
@ -139,26 +139,26 @@ LOGOUT_REDIRECT_URL = 'principal'
AUTH_USER_MODEL = "gestion.ReyMotaUser"
MEDIA_ROOT = os.path.join(BASE_DIR, 'mediafiles/') # 'media' is my media folder
MEDIA_ROOT = os.path.join(BASE_DIR, 'mediafiles/')
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/tmp/debug.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/tmp/debug.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
CSRF_TRUSTED_ORIGINS = ["http://localhost:30443"]

+ 6
- 2
Libros/biblioteca/biblioteca/urls.py View File

@ -20,6 +20,8 @@ from django.conf import settings
from django.conf.urls.static import static
from django.views.generic.base import TemplateView # new
admin.site.site_title = "Demo django con nginx"
urlpatterns = [
path('obreros/', admin.site.urls),
path('gestion/', include('gestion.urls')),
@ -28,9 +30,11 @@ urlpatterns = [
path("accounts/", include("django.contrib.auth.urls")),
path("", TemplateView.as_view(template_name="gestion/index.html"), name="principal"), # new
path("", TemplateView.as_view(template_name="gestion/index.html"),
name="principal"), # new
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)

+ 15
- 8
Libros/biblioteca/gestion/admin.py View File

@ -10,6 +10,7 @@ from .forms import ReyMotaUserCreationForm, ReyMotaUserChangeForm
admin.site.register(Autor)
admin.site.register(Libro)
class ReyMotaUserAdmin(UserAdmin):
add_form = ReyMotaUserCreationForm
form = ReyMotaUserChangeForm
@ -19,21 +20,27 @@ class ReyMotaUserAdmin(UserAdmin):
fieldsets = (
(None, {"fields": ("email", "password")}),
("Personal", {"fields": ("nombre",)}),
("Permissions", {"fields": ("is_staff", "is_active", "groups", "user_permissions")}),
("Permissions", {"fields": ("is_staff", "is_active", "groups",
"user_permissions")}),
("Varios", {"fields": ("foto",)}),
)
add_fieldsets = (
(None, {
"classes": ("wide",),
"fields": (
"email", "password1", "password2", "is_staff",
"is_active", "groups", "user_permissions"
)}
(
None,
{
"classes": ("wide",),
"fields": (
"email", "password1", "password2", "is_staff",
"is_active", "groups", "user_permissions"
)
}
),
("Personal", {"fields": ("nombre",)}),
("Varios", {"fields": ("foto",)}),
)
search_fields = ("email",)
ordering = ("email",)
admin.site.register(ReyMotaUser, ReyMotaUserAdmin)
admin.site.register(ReyMotaUser, ReyMotaUserAdmin)

+ 14
- 5
Libros/biblioteca/gestion/forms.py View File

@ -3,26 +3,34 @@ from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import Autor, Libro, ReyMotaUser
class AutorForm(forms.ModelForm):
class Meta:
model = Autor
fields = ['nombre', 'biografia', 'foto']
nombre = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
biografia = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
nombre = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control'}))
biografia = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control'}))
class LibroForm(forms.ModelForm):
class Meta:
model = Libro
fields = ['titulo', 'autor', 'fecha_publicacion', 'descripcion', 'archivo', 'portada']
fields = ['titulo', 'autor', 'fecha_publicacion', 'descripcion',
'archivo', 'portada']
titulo = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
descripcion = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
titulo = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control'}))
descripcion = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control'}))
autor = forms.ModelChoiceField(
queryset=Autor.objects.all(),
widget=forms.Select(attrs={'class': 'form-control'}))
class ReyMotaUserCreationForm(UserCreationForm):
class Meta:
@ -30,6 +38,7 @@ class ReyMotaUserCreationForm(UserCreationForm):
fields = ("email", "nombre", "foto")
labels = {'email': 'Dirección de correo'}
class ReyMotaUserChangeForm(UserChangeForm):
class Meta:


+ 1
- 1
Libros/biblioteca/gestion/managers.py View File

@ -31,4 +31,4 @@ class ReyMotaUserManager(BaseUserManager):
raise ValueError(_("Superuser must have is_staff=True."))
if extra_fields.get("is_superuser") is not True:
raise ValueError(_("Superuser must have is_superuser=True."))
return self.create_user(email, password, **extra_fields)
return self.create_user(email, password, **extra_fields)

+ 4
- 1
Libros/biblioteca/gestion/models.py View File

@ -6,6 +6,7 @@ from django.utils.translation import gettext_lazy as _
from .managers import ReyMotaUserManager
def current_year():
return datetime.date.today().year
@ -13,6 +14,7 @@ def current_year():
def max_value_current_year(value):
return MaxValueValidator(current_year())(value)
class Autor(models.Model):
nombre = models.CharField(max_length=200)
biografia = models.TextField(blank=True, null=True)
@ -21,6 +23,7 @@ class Autor(models.Model):
def __str__(self):
return self.nombre
class Libro(models.Model):
titulo = models.CharField(max_length=200)
autor = models.ForeignKey(Autor, on_delete=models.CASCADE)
@ -46,4 +49,4 @@ class ReyMotaUser(AbstractBaseUser, PermissionsMixin):
objects = ReyMotaUserManager()
def __str__(self):
return self.email
return self.email

+ 2
- 1
Libros/biblioteca/gestion/templatetags/filtros_de_entorno.py View File

@ -1,8 +1,9 @@
import os
import os
from django import template
register = template.Library()
@register.filter
def muestra_version(clave):
return os.getenv(clave, '')

+ 1
- 1
Libros/biblioteca/gestion/urls.py View File

@ -8,7 +8,7 @@ urlpatterns = [
path('autores/<int:autor_id>/', views.detalle_autor, name='detalle_autor'),
path('autores/<int:autor_id>/editar/', views.editar_autor, name='editar_autor'),
path('autores/<int:autor_id>/eliminar/', views.eliminar_autor, name='eliminar_autor'),
path('libros/', views.lista_libros, name='lista_libros'),
path('libros/nuevo/', views.nuevo_libro, name='nuevo_libro'),
path('libros/<int:libro_id>/', views.detalle_libro, name='detalle_libro'),


+ 12
- 2
Libros/biblioteca/gestion/views.py View File

@ -5,18 +5,20 @@ from django.views.generic import CreateView
from django.contrib.auth.forms import UserCreationForm
from django.urls import reverse_lazy
from .models import Autor, Libro
from .forms import AutorForm, LibroForm
def principal(request):
return render(request, 'gestion/index.html')
# Vistas para los autores
def lista_autores(request):
autores = Autor.objects.all()
return render(request, 'gestion/lista_autores.html', {'autores': autores})
def detalle_autor(request, autor_id):
autor = get_object_or_404(Autor, pk=autor_id)
@ -24,6 +26,7 @@ def detalle_autor(request, autor_id):
return render(request, 'gestion/detalle_autor.html', {'autor': autor, 'libros': libros})
@login_required
def nuevo_autor(request):
if request.method == 'POST':
@ -35,6 +38,7 @@ def nuevo_autor(request):
form = AutorForm()
return render(request, 'gestion/form_autor.html', {'form': form})
@login_required
def editar_autor(request, autor_id):
autor = get_object_or_404(Autor, pk=autor_id)
@ -47,21 +51,25 @@ def editar_autor(request, autor_id):
form = AutorForm(instance=autor)
return render(request, 'gestion/form_autor.html', {'form': form})
@login_required
def eliminar_autor(request, autor_id):
autor = get_object_or_404(Autor, pk=autor_id)
autor.delete()
return redirect('lista_autores')
# Vistas para los libros
def lista_libros(request):
libros = Libro.objects.all()
return render(request, 'gestion/lista_libros.html', {'libros': libros})
def detalle_libro(request, libro_id):
libro = get_object_or_404(Libro, pk=libro_id)
return render(request, 'gestion/detalle_libro.html', {'libro': libro})
@login_required
def nuevo_libro(request):
if request.method == 'POST':
@ -73,6 +81,7 @@ def nuevo_libro(request):
form = LibroForm()
return render(request, 'gestion/form_libro.html', {'form': form})
@login_required
def editar_libro(request, libro_id):
libro = get_object_or_404(Libro, pk=libro_id)
@ -85,6 +94,7 @@ def editar_libro(request, libro_id):
form = LibroForm(instance=libro)
return render(request, 'gestion/form_libro.html', {'form': form})
@login_required
def eliminar_libro(request, libro_id):
libro = get_object_or_404(Libro, pk=libro_id)
@ -95,4 +105,4 @@ def eliminar_libro(request, libro_id):
class SignUpView(CreateView):
form_class = UserCreationForm
success_url = reverse_lazy("login")
template_name = "registration/signup.html"
template_name = "registration/signup.html"

+ 7
- 2
Libros/requirements.txt View File

@ -1,7 +1,12 @@
asgiref==3.8.1
Django==4.2
flake8==7.1.1
gunicorn==22.0.0
mccabe==0.7.0
packaging==24.1
pillow==10.4.0
psycopg2-binary==2.9.6
pycodestyle==2.12.1
pyflakes==3.2.0
sqlparse==0.5.1
typing_extensions==4.12.2
gunicorn==22.0.0
psycopg2-binary==2.9.6

Loading…
Cancel
Save