feat: moved users views to web app

This commit is contained in:
2024-11-30 13:22:09 +01:00
parent 500886aacd
commit e40cdee31b
14 changed files with 121 additions and 128 deletions
+18
View File
@@ -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
+1 -8
View File
@@ -1,13 +1,6 @@
from django.urls import path from django.urls import path
from users.views import login, logout, register, reset_password
app_name = "users" app_name = "users"
urlpatterns = [ urlpatterns = []
path("login/", login, name="login"),
path("logout/", logout, name="logout"),
path("register/", register, name="register"),
path("reset-password/", reset_password, name="reset-password"),
]
-68
View File
@@ -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()
+2 -2
View File
@@ -1,7 +1,7 @@
from django.shortcuts import render from django.shortcuts import render
from django.views.generic import TemplateView from django.views.generic import TemplateView
from shop.filters import ProductFilter 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.mixins import FilteredQuerysetMixin, PaginatedQuerysetMixin
from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME
from web.utils import get_or_create_cart 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): class ListProducts(TemplateView, FilteredQuerysetMixin, PaginatedQuerysetMixin):
template_name = "web/list_products.html" template_name = "web/list_products.html"
queryset = Product.objects.all() queryset = Product.objects.all().prefetch_related('images', )
filter_class = ProductFilter filter_class = ProductFilter
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@@ -27,8 +27,8 @@
<!-- Cart --> <!-- Cart -->
<div id="myCartDropdown1" <div id="myCartDropdown1"
class="absolute top-10 hidden 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"> 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"
>
<div> <div>
{% if cart.items.count == 0 %} {% if cart.items.count == 0 %}
<h2 class="text-sm font-medium text-gray-900 dark:text-white">No hay nada en el carrito</h2> <h2 class="text-sm font-medium text-gray-900 dark:text-white">No hay nada en el carrito</h2>
+1 -1
View File
@@ -76,7 +76,7 @@
{% include 'components/users/user_dropdown.html' %} {% include 'components/users/user_dropdown.html' %}
</div> </div>
{% else %} {% else %}
<a href="{% url 'users:login' %}" <a href="{% url 'web:login' %}"
class="inline-flex items-center rounded-lg justify-center p-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-sm font-medium leading-none text-gray-900 dark:text-white">Inicia class="inline-flex items-center rounded-lg justify-center p-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-sm font-medium leading-none text-gray-900 dark:text-white">Inicia
sesión</a> sesión</a>
{% endif %} {% endif %}
@@ -39,7 +39,7 @@
</ul> </ul>
<div class="p-2 text-sm font-medium text-gray-900 dark:text-white"> <div class="p-2 text-sm font-medium text-gray-900 dark:text-white">
<a href="{% url 'users:logout' %}" title="" <a href="{% url 'web:logout' %}" title=""
class="inline-flex w-full items-center gap-2 rounded-md px-3 py-2 text-sm hover:bg-gray-100 dark:hover:bg-gray-600"> class="inline-flex w-full items-center gap-2 rounded-md px-3 py-2 text-sm hover:bg-gray-100 dark:hover:bg-gray-600">
{% translate 'Cerrar sesión' %} {% translate 'Cerrar sesión' %}
</a> </a>
@@ -15,7 +15,7 @@
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white"> <h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
Sign in to your account Sign in to your account
</h1> </h1>
<form class="space-y-4 md:space-y-6" action="{% url 'users:login' %}" method="post"> <form class="space-y-4 md:space-y-6" action="{% url 'web:login' %}" method="post">
{% csrf_token %} {% csrf_token %}
{% for field in form %} {% for field in form %}
<label for="{{ field.id_for_label }}" <label for="{{ field.id_for_label }}"
+5 -31
View File
@@ -14,13 +14,13 @@
<img class="w-full hidden dark:block" src="{{ product.images.all|first }}" alt=""/> <img class="w-full hidden dark:block" src="{{ product.images.all|first }}" alt=""/>
</div> </div>
<div class="mt-6 sm:mt-8 lg:mt-0"> <div class="my-4 sm:m-8 lg:m-0">
<h1 <h1
class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white" class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white"
> >
{{ product.name }} {{ product.name }}
</h1> </h1>
<div class="mt-4 sm:items-center sm:gap-4 sm:flex"> <div class="my-4 sm:items-center sm:gap-4 sm:flex">
<p <p
class="text-2xl font-extrabold text-gray-900 sm:text-3xl dark:text-white" class="text-2xl font-extrabold text-gray-900 sm:text-3xl dark:text-white"
> >
@@ -109,7 +109,7 @@
</div> </div>
</div> </div>
<div class="mt-6 sm:gap-4 sm:items-center sm:flex sm:mt-8"> <div class="my-4 sm:gap-4 sm:items-center sm:flex sm:m-8">
<a <a
href="#" href="#"
title="" title=""
@@ -136,41 +136,15 @@
{% translate 'Añadir a lista de deseados' %} {% translate 'Añadir a lista de deseados' %}
</a> </a>
<a {% include 'components/cart/add_to_cart.html' %}
href="#"
title=""
class="text-white mt-4 sm:mt-0 bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-primary-600 dark:hover:bg-primary-700 focus:outline-none dark:focus:ring-primary-800 flex items-center justify-center"
role="button"
>
<svg
class="w-5 h-5 -ms-2 me-2"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="none"
viewBox="0 0 24 24"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 4h1.5L8 16m0 0h8m-8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm.75-3H7.5M11 7H6.312M17 4v6m-3-3h6"
/>
</svg>
{% translate 'Añadir al carrito' %}
</a>
</div>
<hr class="my-6 md:my-8 border-gray-200 dark:border-gray-800"/> <hr class="my-6 md:my-8 border-gray-200 dark:border-gray-800"/>
</div>
<p class="mb-6 text-gray-500 dark:text-gray-400"> <p class="mb-6 text-gray-500 dark:text-gray-400">
{{ product.description }} {{ product.description }}
</p> </p>
</div> </div>
</div> </div>
</div>
</section> </section>
{% endblock %} {% endblock %}
@@ -19,7 +19,7 @@ class TestLogin(APITestCase):
def test_login(self): def test_login(self):
response = self.client.post( response = self.client.post(
reverse("users:login"), reverse("web:login"),
{ {
"username": self.user.username, "username": self.user.username,
"password": self.password, "password": self.password,
@@ -30,12 +30,12 @@ class TestLogin(APITestCase):
assert response.url == reverse("web:index") assert response.url == reverse("web:index")
def test_login_get(self): 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 assert response.status_code == status.HTTP_200_OK
def test_login_already_logged_in(self): def test_login_already_logged_in(self):
response = self.client.post( response = self.client.post(
reverse("users:login"), reverse("web:login"),
{ {
"username": self.user.username, "username": self.user.username,
"password": self.password, "password": self.password,
@@ -45,13 +45,13 @@ class TestLogin(APITestCase):
assert response.status_code == status.HTTP_302_FOUND assert response.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index") 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.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index") assert response.url == reverse("web:index")
def test_login_failed(self): def test_login_failed(self):
response = self.client.post( response = self.client.post(
reverse("users:login"), reverse("web:login"),
{ {
"username": self.user.username, "username": self.user.username,
"password": "wrongpassword", "password": "wrongpassword",
@@ -62,7 +62,7 @@ class TestLogin(APITestCase):
def test_login_then_logout(self): def test_login_then_logout(self):
response = self.client.post( response = self.client.post(
reverse("users:login"), reverse("web:login"),
{ {
"username": self.user.username, "username": self.user.username,
"password": self.password, "password": self.password,
@@ -72,18 +72,18 @@ class TestLogin(APITestCase):
assert response.status_code == status.HTTP_302_FOUND assert response.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index") 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.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index") assert response.url == reverse("web:index")
def test_logout_already_logged_out(self): 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.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index") assert response.url == reverse("web:index")
def test_login_then_get_logout(self): def test_login_then_get_logout(self):
response = self.client.post( response = self.client.post(
reverse("users:login"), reverse("web:login"),
{ {
"username": self.user.username, "username": self.user.username,
"password": self.password, "password": self.password,
@@ -93,6 +93,6 @@ class TestLogin(APITestCase):
assert response.status_code == status.HTTP_302_FOUND assert response.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index") 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.status_code == status.HTTP_302_FOUND
assert response.url == reverse("web:index") assert response.url == reverse("web:index")
+9 -1
View File
@@ -1,6 +1,6 @@
from django.urls import path 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 from web.components.views import list_products, cart_dropdown
app_name = "web" app_name = "web"
@@ -9,9 +9,17 @@ app_name = "web"
urlpatterns = [ urlpatterns = [
path("", index, name="index"), path("", index, name="index"),
path("products/<int:pk>/<str:slug>/", product_detail, name="product_detail"), path("products/<int:pk>/<str:slug>/", 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 # components
path("web/components/products/", list_products, name="list_products"), path("web/components/products/", list_products, name="list_products"),
path("web/components/cart-dropdown/", cart_dropdown, name="cart_dropdown"), path("web/components/cart-dropdown/", cart_dropdown, name="cart_dropdown"),
# api # api
path("web/add-cart-item/", add_cart_item, name="add_cart_item"), path("web/add-cart-item/", add_cart_item, name="add_cart_item"),
path("web/delete-cart-item/<int:pk>/", delete_cart_item, name="delete_cart_item"), path("web/delete-cart-item/<int:pk>/", delete_cart_item, name="delete_cart_item"),
+70 -2
View File
@@ -1,13 +1,76 @@
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.views.generic import TemplateView
from django.http.response import HttpResponse from django.http.response import HttpResponse
from django.views.decorators.http import require_http_methods 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.utils import get_or_create_cart
from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME 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): class IndexView(TemplateView):
template_name = "web/index.html" template_name = "web/index.html"
@@ -76,3 +139,8 @@ def delete_cart_item(request, pk, *args, **kwargs):
index = IndexView.as_view() index = IndexView.as_view()
product_detail = ProductDetail.as_view() product_detail = ProductDetail.as_view()
login = LoginView.as_view()
logout = LogoutView.as_view()
register = RegisterView.as_view()
reset_password = ResetPasswordView.as_view()