diff --git a/config/models.py b/config/models.py
new file mode 100644
index 0000000..7d55579
--- /dev/null
+++ b/config/models.py
@@ -0,0 +1,18 @@
+from django.db import models
+
+
+class SingletonModel(models.Model):
+ class Meta:
+ abstract = True
+
+ def save(self, *args, **kwargs):
+ self.pk = 1
+ super(SingletonModel, self).save(*args, **kwargs)
+
+ def delete(self, *args, **kwargs):
+ pass
+
+ @classmethod
+ def load(cls):
+ obj, created = cls.objects.get_or_create(pk=1)
+ return obj
diff --git a/users/urls.py b/users/urls.py
index 0d2dc8f..df4c419 100644
--- a/users/urls.py
+++ b/users/urls.py
@@ -1,13 +1,6 @@
from django.urls import path
-from users.views import login, logout, register, reset_password
-
app_name = "users"
-urlpatterns = [
- path("login/", login, name="login"),
- path("logout/", logout, name="logout"),
- path("register/", register, name="register"),
- path("reset-password/", reset_password, name="reset-password"),
-]
+urlpatterns = []
diff --git a/users/views.py b/users/views.py
index 907fff5..e69de29 100644
--- a/users/views.py
+++ b/users/views.py
@@ -1,68 +0,0 @@
-from django.contrib.auth import login as login_user
-from django.contrib.auth import logout as logout_user
-from django.shortcuts import redirect, render, reverse
-from django.views.generic import TemplateView, View
-
-from users.forms import LoginForm
-
-
-class RedirectionMixin:
- redirect_to = ""
-
- def get_redirection(self):
- return reverse(self.redirect_to)
-
-
-class LoginView(View, RedirectionMixin):
- template_name = "users/login.html"
- redirect_to = "web:index"
- login_form_class = LoginForm
-
- def get_login_form(self, request):
- return self.login_form_class(data=request.POST)
-
- def get(self, request, *args, **kwargs):
- if request.user.is_authenticated:
- return redirect(self.get_redirection())
-
- login_form = self.login_form_class()
- return render(request, self.template_name, {"form": login_form})
-
- def post(self, request, *args, **kwargs):
- login_form = self.get_login_form(request)
-
- if login_form.is_valid():
- login_user(request, login_form.get_user())
-
- if not login_form.cleaned_data.get('remember_me'):
- request.session.set_expiry(0)
-
- return redirect(self.get_redirection())
-
- return render(request, self.template_name, {"form": login_form}, status=400)
-
-
-class LogoutView(View, RedirectionMixin):
- redirect_to = "web:index"
-
- def get(self, request, *args, **kwargs):
- logout_user(request)
- return redirect(self.get_redirection())
-
- def post(self, request, *args, **kwargs):
- logout_user(request)
- return redirect(self.get_redirection())
-
-
-class RegisterView(TemplateView):
- template_name = "users/register.html"
-
-
-class ResetPasswordView(TemplateView):
- template_name = "users/reset-password.html"
-
-
-login = LoginView.as_view()
-logout = LogoutView.as_view()
-register = RegisterView.as_view()
-reset_password = ResetPasswordView.as_view()
diff --git a/web/components/views.py b/web/components/views.py
index 223c3e7..02b143b 100644
--- a/web/components/views.py
+++ b/web/components/views.py
@@ -1,7 +1,7 @@
from django.shortcuts import render
from django.views.generic import TemplateView
from shop.filters import ProductFilter
-from shop.models import Product, Cart
+from shop.models import Product, Cart, ProductPrice
from web.mixins import FilteredQuerysetMixin, PaginatedQuerysetMixin
from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME
from web.utils import get_or_create_cart
@@ -9,7 +9,7 @@ from web.utils import get_or_create_cart
class ListProducts(TemplateView, FilteredQuerysetMixin, PaginatedQuerysetMixin):
template_name = "web/list_products.html"
- queryset = Product.objects.all()
+ queryset = Product.objects.all().prefetch_related('images', )
filter_class = ProductFilter
def get_context_data(self, **kwargs):
diff --git a/web/templates/components/cart/cart_navbar.html b/web/templates/components/cart/cart_navbar.html
index 7dc320b..78c7935 100644
--- a/web/templates/components/cart/cart_navbar.html
+++ b/web/templates/components/cart/cart_navbar.html
@@ -27,8 +27,8 @@
-
+ class="absolute top-10 z-10 mx-auto max-w-sm space-y-4 overflow-hidden rounded-lg bg-white p-4 antialiased shadow-lg dark:bg-gray-800 hidden"
+>
{% if cart.items.count == 0 %}
No hay nada en el carrito
diff --git a/web/templates/components/generic/navbar.html b/web/templates/components/generic/navbar.html
index 7deaa69..18b0c7a 100644
--- a/web/templates/components/generic/navbar.html
+++ b/web/templates/components/generic/navbar.html
@@ -76,7 +76,7 @@
{% include 'components/users/user_dropdown.html' %}
{% else %}
-
Inicia
sesión
{% endif %}
diff --git a/web/templates/components/users/user_dropdown.html b/web/templates/components/users/user_dropdown.html
index fff6665..5d8ff89 100644
--- a/web/templates/components/users/user_dropdown.html
+++ b/web/templates/components/users/user_dropdown.html
@@ -39,7 +39,7 @@
-
{% translate 'Cerrar sesión' %}
diff --git a/users/templates/users/login.html b/web/templates/users/login.html
similarity index 96%
rename from users/templates/users/login.html
rename to web/templates/users/login.html
index c5e0240..246dc75 100644
--- a/users/templates/users/login.html
+++ b/web/templates/users/login.html
@@ -15,7 +15,7 @@
Sign in to your account
-
-
+
{{ product.name }}
-
-
+
-
-
-
{{ product.description }}
-
{% endblock %}
diff --git a/users/tests/test_login.py b/web/tests/test_login.py
similarity index 84%
rename from users/tests/test_login.py
rename to web/tests/test_login.py
index 08fedc3..0f0a7a4 100644
--- a/users/tests/test_login.py
+++ b/web/tests/test_login.py
@@ -19,7 +19,7 @@ class TestLogin(APITestCase):
def test_login(self):
response = self.client.post(
- reverse("users:login"),
+ reverse("web:login"),
{
"username": self.user.username,
"password": self.password,
@@ -30,12 +30,12 @@ class TestLogin(APITestCase):
assert response.url == reverse("web:index")
def test_login_get(self):
- response = self.client.get(reverse("users:login"))
+ response = self.client.get(reverse("web:login"))
assert response.status_code == status.HTTP_200_OK
def test_login_already_logged_in(self):
response = self.client.post(
- reverse("users:login"),
+ reverse("web:login"),
{
"username": self.user.username,
"password": self.password,
@@ -45,13 +45,13 @@ class TestLogin(APITestCase):
assert response.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index")
- response = self.client.get(reverse("users:login"))
+ response = self.client.get(reverse("web:login"))
assert response.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index")
def test_login_failed(self):
response = self.client.post(
- reverse("users:login"),
+ reverse("web:login"),
{
"username": self.user.username,
"password": "wrongpassword",
@@ -62,7 +62,7 @@ class TestLogin(APITestCase):
def test_login_then_logout(self):
response = self.client.post(
- reverse("users:login"),
+ reverse("web:login"),
{
"username": self.user.username,
"password": self.password,
@@ -72,18 +72,18 @@ class TestLogin(APITestCase):
assert response.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index")
- response = self.client.post(reverse("users:logout"))
+ response = self.client.post(reverse("web:logout"))
assert response.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index")
def test_logout_already_logged_out(self):
- response = self.client.post(reverse("users:logout"))
+ response = self.client.post(reverse("web:logout"))
assert response.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index")
def test_login_then_get_logout(self):
response = self.client.post(
- reverse("users:login"),
+ reverse("web:login"),
{
"username": self.user.username,
"password": self.password,
@@ -93,6 +93,6 @@ class TestLogin(APITestCase):
assert response.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index")
- response = self.client.get(reverse("users:logout"))
+ response = self.client.get(reverse("web:logout"))
assert response.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index")
diff --git a/web/urls.py b/web/urls.py
index 69eaaa4..2bb90cf 100644
--- a/web/urls.py
+++ b/web/urls.py
@@ -1,6 +1,6 @@
from django.urls import path
-from web.views import index, product_detail, add_cart_item, delete_cart_item
+from web.views import index, product_detail, add_cart_item, delete_cart_item, login, logout, register, reset_password
from web.components.views import list_products, cart_dropdown
app_name = "web"
@@ -9,9 +9,17 @@ app_name = "web"
urlpatterns = [
path("", index, name="index"),
path("products/
//", product_detail, name="product_detail"),
+
+ # users
+ path("login/", login, name="login"),
+ path("logout/", logout, name="logout"),
+ path("register/", register, name="register"),
+ path("reset-password/", reset_password, name="reset-password"),
+
# components
path("web/components/products/", list_products, name="list_products"),
path("web/components/cart-dropdown/", cart_dropdown, name="cart_dropdown"),
+
# api
path("web/add-cart-item/", add_cart_item, name="add_cart_item"),
path("web/delete-cart-item//", delete_cart_item, name="delete_cart_item"),
diff --git a/web/views.py b/web/views.py
index 8bfa603..074286d 100644
--- a/web/views.py
+++ b/web/views.py
@@ -1,13 +1,76 @@
from django.shortcuts import get_object_or_404
-from django.views.generic import TemplateView
from django.http.response import HttpResponse
from django.views.decorators.http import require_http_methods
-from shop.models import Product, Cart, CartItem
+from shop.models import Product, CartItem
from web.utils import get_or_create_cart
from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME
+from django.contrib.auth import login as login_user
+from django.contrib.auth import logout as logout_user
+from django.shortcuts import redirect, render, reverse
+from django.views.generic import TemplateView, View
+
+from users.forms import LoginForm
+
+
+class RedirectionMixin:
+ redirect_to = ""
+
+ def get_redirection(self):
+ return reverse(self.redirect_to)
+
+
+class LoginView(View, RedirectionMixin):
+ template_name = "users/login.html"
+ redirect_to = "web:index"
+ login_form_class = LoginForm
+
+ def get_login_form(self, request):
+ return self.login_form_class(data=request.POST)
+
+ def get(self, request, *args, **kwargs):
+ if request.user.is_authenticated:
+ return redirect(self.get_redirection())
+
+ login_form = self.login_form_class()
+ return render(request, self.template_name, {"form": login_form})
+
+ def post(self, request, *args, **kwargs):
+ login_form = self.get_login_form(request)
+
+ if login_form.is_valid():
+ login_user(request, login_form.get_user())
+
+ if not login_form.cleaned_data.get('remember_me'):
+ request.session.set_expiry(0)
+
+ return redirect(self.get_redirection())
+
+ return render(request, self.template_name, {"form": login_form}, status=400)
+
+
+class LogoutView(View, RedirectionMixin):
+ redirect_to = "web:index"
+
+ def get(self, request, *args, **kwargs):
+ logout_user(request)
+ return redirect(self.get_redirection())
+
+ def post(self, request, *args, **kwargs):
+ logout_user(request)
+ return redirect(self.get_redirection())
+
+
+class RegisterView(TemplateView):
+ template_name = "web/register.html"
+
+
+class ResetPasswordView(TemplateView):
+ template_name = "web/reset-password.html"
+
+
class IndexView(TemplateView):
template_name = "web/index.html"
@@ -76,3 +139,8 @@ def delete_cart_item(request, pk, *args, **kwargs):
index = IndexView.as_view()
product_detail = ProductDetail.as_view()
+
+login = LoginView.as_view()
+logout = LogoutView.as_view()
+register = RegisterView.as_view()
+reset_password = ResetPasswordView.as_view()