Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ProyectoFinalDjango
Submodule ProyectoFinalDjango added at 7ba05f
34 changes: 33 additions & 1 deletion app/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
# ------------------------------------------------------------------------------------------------------------------------------------------------------------


# FORM DE PRODUCTO
class ProductCreateForms(forms.ModelForm):
class Meta:
model = Producto
fields = ("articulo", "seccion", "descripcion", "precio_unitario", "imagen")
widgets = {
'seccion': forms.Select(attrs={'class': 'form-select'}),
}


# ------------------------------------------------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -56,3 +58,33 @@ class UserEditForm(UserCreationForm):
class Meta:
model = User
fields = ["email", "password1", "password2", "last_name", "first_name"]

#----------------------------

from django import forms
from .models import Comentario

class ComentarioForm(forms.ModelForm):
class Meta:
model = Comentario
fields = ['texto']

#----------------------

from django.views import View
from django.shortcuts import render, redirect

class ProductCreateView(View):
def get(self, request, *args, **kwargs):
form = ProductCreateForms()
print(form.fields['seccion'].widget) # <-- para verificar que es un Select
context = {'form': form}
return render(request, 'crear_producto.html', context)

def post(self, request):
form = ProductCreateForms(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('app:productos')
context = {'form': form}
return render(request, 'crear_producto.html', context)
34 changes: 22 additions & 12 deletions app/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models

# Create your models here.
from django.contrib.auth.models import User # <-- Importa User
from datetime import datetime


# Clase Cliente
Expand All @@ -15,11 +15,12 @@ class Cliente(models.Model):
def __str__(self) -> str:
return f"Nombre: {self.nombre} | Apellido: {self.apellido} | Dirección: {self.direccion} | email: {self.email} | telefono: {self.telefono}"

# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------------------------------------------------------------------------------------

from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MaxValueValidator, MinValueValidator

# Clase Producto
class Producto(models.Model):
GENERO_CHOICES = [
("ACC", "Acción"),
Expand All @@ -41,15 +42,13 @@ class Producto(models.Model):
help_text="Puntaje de 1 a 5 estrellas",
)
imagen = models.ImageField("Portada", null=True, blank=True)
usuario = models.ForeignKey(User, on_delete=models.CASCADE, related_name='productos', null=True, blank=True)
fecha_publicacion = models.DateTimeField(auto_now_add=True)

def __str__(self) -> str:
return (
f"{self.articulo} ({self.get_seccion_display()}) - {self.precio_unitario}★"
)


# ------------------------------------------------------------------------------------------------------------------------------------------------------------
return f"{self.articulo} ({self.get_seccion_display()}) - {self.precio_unitario}★"

# ------------------------------------------------------------------------------

# Clase Contacto (Feedback Clientes)
class Contacto(models.Model):
Expand All @@ -62,5 +61,16 @@ class Contacto(models.Model):
def __str__(self) -> str:
return f"Mensaje - Asunto: {self.asunto} | Mensaje: {self.mensaje}"

# ------------------------------------------------------------------------------

class Comentario(models.Model):
producto = models.ForeignKey(Producto, on_delete=models.CASCADE, related_name='comentarios')
texto = models.TextField()
creado_en = models.DateTimeField(auto_now_add=True)
usuario = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comentarios', null=True, blank=True)

def __str__(self):
return f'Comentario en {self.producto.articulo} - {self.creado_en}'



# ------------------------------------------------------------------------------------------------------------------------------------------------------------
14 changes: 12 additions & 2 deletions app/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
# AGERGADO PARA EL LOGOUT
from django.contrib.auth.views import LogoutView
from django.contrib.auth.views import LogoutView, LoginView as auth_views_LoginView
from django.urls import path
from . import views

from app.views import *

# Import productos_list if it's defined elsewhere, otherwise define it in views.py
try:
from app.views import productos_list
except ImportError:
pass # productos_list should be defined in app/views.py

app_name = "app"

urlpatterns = [
Expand All @@ -15,9 +22,12 @@
path("contacto/", ContactCreateView.as_view(), name="contacto"),
path("<int:pk>/modificar/", ProductUpdateView.as_view(), name="modificar_producto"),
path("<int:pk>/delete/", ProductDeleteView.as_view(), name="borrar_producto"),
path("login", login_request, name="login"),
path("registro", register, name="registro"),
path("editar_perfil", EditProfile, name="editar_perfil"),
path("logout", LogoutView.as_view(), name="logout"),
path("nosotros/", AboutUsView, name="nosotros"),
path('pelicula/<int:pk>/', views.producto_detalle, name='producto_detalle'),
path('login/', auth_views_LoginView.as_view(template_name='login.html'), name='login'),
]


123 changes: 90 additions & 33 deletions app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,21 @@
from django.core.mail import EmailMessage
from django.conf import settings

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.utils.decorators import method_decorator
from django.contrib.auth.models import User


#----------------------------------------------------------------------------------------------

## VISTAS DE CLIENTE
# Vista de Clase que lista los clientes

class ClientListView(ListView):
def get(self,request):
clientes = Cliente.objects.all()
context = {
'clientes':clientes
}
return render(request,'clientes_list.html',context)
def get(self, request):
clientes = User.objects.all()
return render(request, 'clientes_list.html', {'clientes': clientes})


#----------------------------------------------------------------------------------------------

Expand Down Expand Up @@ -63,50 +67,48 @@ def ToFindProductView(request):


# Vista de clase - permite crear un nuevo Producto
class ProductCreateView(View):
def get(self,request,*args,**kwargs):
#parte creada para llamar el contenido del en forms.py (donde generamos producto)

class ProductCreateView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
form = ProductCreateForms()
context={
'form':form
}
return render(request,'crear_producto.html',context)
def post(self,request):
if request.method=="POST":
form = ProductCreateForms(request.POST,request.FILES)
if form.is_valid():
articulo = form.cleaned_data.get('articulo')
seccion = form.cleaned_data.get('seccion')
descripcion = form.cleaned_data.get('descripcion')
precio_unitario = form.cleaned_data.get('precio_unitario')
imagen = form.cleaned_data.get('imagen')
return render(request, 'crear_producto.html', {'form': form})

p, created = Producto.objects.get_or_create(articulo=articulo,seccion=seccion,descripcion=descripcion,precio_unitario=precio_unitario,imagen=imagen)
p.save()
return redirect('app:productos')
def post(self, request):
form = ProductCreateForms(request.POST, request.FILES)
if form.is_valid():
producto = form.save(commit=False)
producto.usuario = request.user # guardo usuario actual
producto.save()
return redirect('app:productos')

return render(request, 'crear_producto.html', {'form': form})

context = {
}
return render(request,'crear_producto.html',context)


# Vista de clase que permite modificar (update) nuestro producto
class ProductUpdateView(UpdateView):

class ProductUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Producto
fields = ['articulo','seccion','descripcion','precio_unitario','imagen']
fields = ['articulo', 'seccion', 'descripcion', 'precio_unitario', 'imagen']
template_name = 'modifcar_producto.html'

def get_success_url(self):
pk = self.kwargs['pk']
return reverse_lazy('app:productos')

def test_func(self):
producto = self.get_object()
return self.request.user == producto.usuario


# Vista de clase que nos permite eliminar un producto
class ProductDeleteView(DeleteView):
class ProductDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Producto
template_name = 'borrar_producto.html'
success_url = reverse_lazy('app:productos')

def test_func(self):
producto = self.get_object()
return self.request.user == producto.usuario

#----------------------------------------------------------------------------------------------

## VISTAS DE CONTACTO
Expand Down Expand Up @@ -262,3 +264,58 @@ def AboutUsView(request):
}
return render(request,"nosotros.html",context)

#--------------------
from django.shortcuts import render, get_object_or_404, redirect
from .models import Producto, Comentario
from django.contrib.auth.decorators import login_required
# Vista de detalle del producto

def producto_detalle(request, pk):
producto = get_object_or_404(Producto, pk=pk)
comentarios = producto.comentarios.order_by('-creado_en')

if request.method == 'POST':
if not request.user.is_authenticated:
# Redirigir a login o mostrar mensaje de error
return redirect(f'/login/?next=/app/pelicula/{pk}/') # o la url que uses

texto = request.POST.get('comentario')
if texto:
Comentario.objects.create(producto=producto, texto=texto, usuario=request.user)
return redirect('app:producto_detalle', pk=pk)

return render(request, 'producto_detalle.html', {
'producto': producto,
'comentarios': comentarios,
})


#-----------------------
from django.shortcuts import render
from .models import Producto

def productos_list(request):
orden = request.GET.get('orden', '')

productos = Producto.objects.all()


if orden == 'fecha_asc':
productos = productos.order_by('fecha_publicacion')
elif orden == 'fecha_desc':
productos = productos.order_by('-fecha_publicacion')
elif orden == 'alf_asc':
productos = productos.order_by('articulo')
elif orden == 'alf_desc':
productos = productos.order_by('-articulo')

context = {
'productos': productos,
'orden_actual': orden
}

return render(request, 'app/productos_list.html', context)




5 changes: 4 additions & 1 deletion core/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,7 @@

# --- Crispy Forms ---
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap4"
CRISPY_TEMPLATE_PACK = "bootstrap4"
CRISPY_TEMPLATE_PACK = "bootstrap4"

LOGIN_URL = '/login/'
LOGIN_REDIRECT_URL = '/'
3 changes: 3 additions & 0 deletions core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@

# VISTAS LOGIN_REQUEST Y REGISTER AGREGAR EN VERSION FINAL!!
from core.views import HomeView
from django.contrib.auth.views import LoginView

urlpatterns = [
path("admin/", admin.site.urls),
path("", HomeView, name="inicio"), # llamamos nuestra página de inicio - "hOME"
path("app/", include("app.urls")), # incluímos url's de la app
path("login/", LoginView.as_view(template_name="login.html"), name="login"),
]

if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

1 change: 1 addition & 0 deletions core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ def HomeView(request):


# ------------------------------------------------------------------------------

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 21 additions & 14 deletions templates/buscar_producto.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
{% extends "padre.html" %}
{% load static %}
{% block loquecambia %}
<h2 style="font-size: 3em; text-align: center; margin-top: 3em;">🔎</h2>
<h3 style="text-align: center;"><strong>BÚSQUEDA</strong></h3>
<div style="height: 38.1vh; display: flex; justify-content: center; align-items: center; flex-direction: column; margin-top: -2em;">
<form action="/app/producto_buscado/" method="GET" style="margin-left: 10px;">
<input type="text" name="articulo">
<input type="submit" value="Buscar" style="padding: 2px; border-radius: 5px; background-color: rgb(33,136,56);color: white;">
</form>
<br>
<button class="btn btn-success" style="margin-left: 10px; margin-top: 1em; width: 16.5em"><a href="{% url 'app:productos' %}" style="padding:10px; text-decoration: none; color: white;">Volver a productos</a></button>
<br>
<br>

<div class="container py-5 text-center">
<h2 class="mb-2" style="font-size: 3em;">🔎</h2>
<h3 class="fw-bold" style="color: #ffc107;">BÚSQUEDA</h3>

<div class="d-flex flex-column align-items-center mt-4" style="height: 38.1vh;">
<form action="/app/producto_buscado/" method="GET" class="d-flex" style="gap: 8px;">
<input type="text" name="articulo"
style="padding: 6px 10px; border-radius: 8px; border: 1px solid rgba(255,255,255,0.2); background-color: #1b1b1b; color: white; outline: none;">
<input type="submit" value="Buscar"
style="padding: 6px 14px; border-radius: 8px; background-color: #ffc107; color: #212529; border: none; font-weight: 600;">
</form>

<button class="btn mt-4" style="background-color: #ffc107; border: none; border-radius: 999px; padding: 0.6em 2em; font-weight: 600; box-shadow: 0 6px 15px rgba(0,0,0,0.4);">
<a href="{% url 'app:productos' %}" style="text-decoration: none; color: #212529;">Volver a productos</a>
</button>
</div>
</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"></script>
{% endblock %}

{% endblock %}
Loading
Loading