Implementado Unstuck y Cambio de correo

This commit is contained in:
adevopg
2024-11-29 20:52:11 +01:00
parent 5e1937d245
commit 07b1281d61
21 changed files with 494 additions and 36 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4
View File
@@ -17,6 +17,10 @@ class Noticia(models.Model):
def __str__(self): def __str__(self):
return self.titulo return self.titulo
class UnstuckHistory(models.Model):
character_name = models.CharField(max_length=50)
used_at = models.DateTimeField()
class ClienteCategoria(models.Model): class ClienteCategoria(models.Model):
nombre = models.CharField(max_length=100) nombre = models.CharField(max_length=100)
@@ -1,25 +1,16 @@
$(document).ready(function() { $(document).ready(function() {
$('#nw-change-email-form').on('submit', function(e) { function handleResponse(response, button, originalText) {
e.preventDefault(); // Evitar el envío por defecto del formulario
$("#change-email-response").empty();
var form = $(this);
var button = $('.change-email-button');
var originalText = button.html();
button.html("Cambiando correo...");
button.prop("disabled", true);
$.ajax({
type: 'POST',
url: form.attr('action'),
data: form.serialize(), // Serializar los datos correctamente
dataType: 'json',
success: function(response) {
$("#change-email-response").html(response.message).hide().slideDown(); $("#change-email-response").html(response.message).hide().slideDown();
if (response.redirect_url) {
setTimeout(function() {
window.location.href = response.redirect_url;
}, 2000);
return;
}
if (response.success) { if (response.success) {
button.html("Correo cambiado"); button.html("Proceso completado");
} else { } else {
setTimeout(function() { setTimeout(function() {
$("#change-email-response").slideUp(function() { $("#change-email-response").slideUp(function() {
@@ -29,6 +20,26 @@ $(document).ready(function() {
}); });
}, 5000); }, 5000);
} }
}
// Manejar los enlaces de confirmación
$('.confirm-link').on('click', function(e) {
e.preventDefault();
$("#change-email-response").empty();
var button = $(this);
var url = button.attr('href');
var originalText = button.html();
button.html("Verificando...");
button.prop("disabled", true);
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success: function(response) {
handleResponse(response, button, originalText);
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
console.error("Error:", error); console.error("Error:", error);
@@ -0,0 +1,41 @@
$(function() {
$('.unstuck-button').on('click', function(e) {
e.preventDefault();
e.stopPropagation();
$("#unstuck-response").empty();
var button = $(this);
var originalText = button.html();
var data = $("#uw-unstuck-form").serialize();
button.html("Desbloqueando...");
button.prop("disabled", true);
$.ajax({
type: 'POST',
url: '',
data: data,
dataType: 'json',
success: function(data) {
$("#unstuck-response").html(data.message).hide().slideDown();
if (data.success) {
button.html("Desbloqueado");
setTimeout(function() {
$("#uw-unstuck-form")[0].reset();
button.html(originalText);
button.prop("disabled", false);
}, 5000);
} else {
button.html(originalText);
button.prop("disabled", false);
}
},
error: function() {
$("#unstuck-response").html('<span class="red-form-response">Algo ha salido mal. Inténtelo más tarde.</span>');
button.html(originalText);
button.prop("disabled", false);
}
});
});
});
@@ -0,0 +1,9 @@
<!DOCTYPE html>
{% include 'partials/head.html' %}
{% include 'partials/header.html' %}
{% include 'partials/video.html' %}
{% include 'partials/confirm_new_email_success.html' %}
{% include 'partials/social.html' %}
{% include 'partials/footer.html' %}
{% include 'partials/final.html' %}
@@ -0,0 +1,9 @@
<!DOCTYPE html>
{% include 'partials/head.html' %}
{% include 'partials/header.html' %}
{% include 'partials/video.html' %}
{% include 'partials/confirm_old_email_success.html' %}
{% include 'partials/social.html' %}
{% include 'partials/footer.html' %}
{% include 'partials/final.html' %}
+9
View File
@@ -0,0 +1,9 @@
<!DOCTYPE html>
{% include 'partials/head.html' %}
{% include 'partials/header.html' %}
{% include 'partials/video.html' %}
{% include 'partials/expired_link.html' %}
{% include 'partials/social.html' %}
{% include 'partials/footer.html' %}
{% include 'partials/final.html' %}
@@ -0,0 +1,9 @@
<!DOCTYPE html>
{% include 'partials/head.html' %}
{% include 'partials/header.html' %}
{% include 'partials/video.html' %}
{% include 'partials/unstuck_character.html' %}
{% include 'partials/social.html' %}
{% include 'partials/footer.html' %}
{% include 'partials/final.html' %}
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Confirmación de Nuevo Correo</title>
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body>
<div class="main-container">
<h1>Cambio de Correo Completado</h1>
<p>El cambio de correo ha sido confirmado y completado con éxito.</p>
<a href="{% url 'my-account' %}">Regresar a Mi Cuenta</a>
</div>
</body>
</html>
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Confirmación de Correo Anterior</title>
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body>
<div class="main-container">
<h1>Confirmación de Correo Anterior Exitosa</h1>
<p>Has confirmado tu correo anterior. Se ha enviado un enlace al nuevo correo para completar el cambio.</p>
<a href="{% url 'my-account' %}">Regresar a Mi Cuenta</a>
</div>
</body>
</html>
+27
View File
@@ -0,0 +1,27 @@
<div class="main-page">
<div class="middle-content">
<div class="body-content">
<div class="title-content">
<h1>Enlace Expirado</h1>
</div>
<div class="box-content">
<div class="title-box-content">
<h2>Enlace Expirado</h2>
<a class="back-to-account" href="{% url 'my-account' %}">Regresar a mi cuenta</a>
<a class="back-to-account-responsive" href="{% url 'my-account' %}">Regresar</a>
</div>
<div class="body-box-content justified">
<div class="centered">
<br>
<div class="alert-message">
<span class="red-form-response">Lo sentimos, el enlace que ha utilizado ha expirado o no es válido.</span>
</div>
<br>
<span>No hay códigos de promoción disponibles</span>
<a class="back-to-account" href="{% url 'expired-link' %}">Solicitar nuevo cambio de correo</a>
</div>
</div>
</div>
</div>
</div>
</div>
+1
View File
@@ -52,6 +52,7 @@
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/change_password_response.js"></script> <script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/change_password_response.js"></script>
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/rename_guild_response.js"></script> <script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/rename_guild_response.js"></script>
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/vote_points_response.js"></script> <script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/vote_points_response.js"></script>
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/unstuck_response.js"></script>
<script>var aowow_tooltips = { "colorlinks": true, "iconizelinks": true, "renamelinks": true }</script> <script>var aowow_tooltips = { "colorlinks": true, "iconizelinks": true, "renamelinks": true }</script>
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js/nw-scripts.js"></script> <script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js/nw-scripts.js"></script>
+195
View File
@@ -207,6 +207,201 @@
</tbody></table> </tbody></table>
<br> <br>
</div> </div>
{% for character in characters %}
<div id="character-settings">OPCIONES DE PERSONAJE <i class="fas fa-arrow-down fa-arrow-down-character rotate2"></i>
</div>
<div id="character-settings-panel" style="display: none;">
<table class="max-center-table fixed-layout-table">
<tbody><tr>
<td>
<a href="unstuck-character">
<div class="tool-button">
<div class="acc-icon unstuck-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Desbloquear personaje</span>
<br>
<span class="second-brown shadow">Para personajes atascados</span>
</div>
</div>
</a>
</td>
<td>
<a href="revive-character">
<div class="tool-button">
<div class="acc-icon revive-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Revivir personaje</span>
<br>
<span class="second-brown shadow">¿Nadie más te quiere revivir?</span>
</div>
</div>
</a>
</td>
</tr>
<tr>
<td>
<a href="rename-character">
<div class="tool-button">
<div class="acc-icon rename-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Renombrar personaje</span>
<br>
<span class="second-brown shadow">Adquiere un nombre diferente</span>
</div>
</div>
</a>
</td>
<td>
<a href="customize-character">
<div class="tool-button">
<div class="acc-icon customize-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Personalizar personaje</span>
<br>
<span class="second-brown shadow">Un cambio de look para renovarse</span>
</div>
</div>
</a>
</td>
</tr>
<tr>
<td>
<a href="change-race-character">
<div class="tool-button">
<div class="acc-icon change-race-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Cambiar de raza</span>
<br>
<span class="second-brown shadow">Elije una nueva raza acorde a tu clase</span>
</div>
</div>
</a>
</td>
<td>
<a href="change-faction-character">
<div class="tool-button">
<div class="acc-icon change-faction-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Cambiar de facción</span>
<br>
<span class="second-brown shadow">Vive nuevas aventuras en la facción opuesta</span>
</div>
</div>
</a>
</td>
</tr>
<tr>
<td>
<a href="level-up-character">
<div class="tool-button">
<div class="acc-icon level-up-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Subir a nivel 80</span>
<br>
<span class="second-brown shadow">Para los que no quieren levear</span>
</div>
</div>
</a>
</td>
<td>
<a href="gold-character">
<div class="tool-button">
<div class="acc-icon gold-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Adquirir oro</span>
<br>
<span class="second-brown shadow">Consigue más oro para tu personaje</span>
</div>
</div>
</a>
</td>
</tr>
<tr>
<td>
<a href="quest-character">
<div class="tool-button">
<div class="acc-icon quest-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Rastreador de misiones</span>
<br>
<span class="second-brown shadow">Ayuda con cadenas de misiones importantes</span>
</div>
</div>
</a>
</td>
<td>
<a href="transfer-character">
<div class="tool-button">
<div class="acc-icon tranfer-char-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Transferir personaje</span>
<br>
<span class="second-brown shadow">Mueve tus personajes a otra cuenta</span>
</div>
</div>
</a>
</td>
</tr>
<tr>
<td>
<a href="restore-character">
<div class="tool-button">
<div class="acc-icon restore-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Recuperar personaje</span>
<br>
<span class="second-brown shadow">Restaura un personaje borrado</span>
</div>
</div>
</a>
</td>
<td>
<a href="restore-items">
<div class="tool-button">
<div class="acc-icon prox-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Recuperar ítems</span>
<br>
<span class="second-brown shadow">Restaura objetos borrados</span>
</div>
</div>
</a>
</td>
</tr>
<tr>
<td>
<a href="store-bennu">
<div class="tool-button">
<div class="acc-icon store-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Tienda</span>
<br>
<span class="second-brown shadow">Adquiere objetos de todo tipo</span>
</div>
</div>
</a>
</td>
<td>
<a href="send-gift">
<div class="tool-button">
<div class="acc-icon promo-icon"></div>
<div class="tool-button-div">
<span class="first-brown shadow">Enviar regalo</span>
<br>
<span class="second-brown shadow">Envía regalos a tus amigos</span>
</div>
</div>
</a>
</td>
</tr>
</tbody></table>
<br>
{% endfor %}
</div>
<div id="account-history">HISTORIALES <i class="fas fa-arrow-down fa-arrow-down-history rotate2"></i></div> <div id="account-history">HISTORIALES <i class="fas fa-arrow-down fa-arrow-down-history rotate2"></i></div>
<div id="account-history-panel"> <div id="account-history-panel">
<table class="max-center-table fixed-layout-table"> <table class="max-center-table fixed-layout-table">
@@ -0,0 +1,43 @@
<div class="main-page">
<div class="middle-content">
<div class="body-content">
<div class="title-content">
<h1>Desbloquear personaje</h1>
</div>
<div class="box-content">
<div class="title-box-content">
<h2>Información</h2>
<a class="back-to-account" href="{% url 'my-account' %}">Regresar a mi cuenta</a>
<a class="back-to-account-responsive" href="{% url 'my-account' %}">Regresar</a>
</div>
<div class="body-box-content justified">
<p>La herramienta <span>Desbloquear personaje</span> te permite desbloquear un personaje que esté atascado y lo mueve a la ubicación de su Piedra Hogar.</p>
<p>Usa esta opción cuando tu personaje se encuentre atrapado y ninguna otra opción te sirva.</p>
<fieldset>
<legend>NOTA</legend>
<div class="separate2">
<p>Se requiere que el personaje esté desconectado.</p>
<p>Se puede repetir la acción en un mismo personaje cada 12 horas.</p>
</div>
</fieldset>
<div class="centered">
<p>Escoge el personaje que quieres desbloquear</p>
<form id="uw-unstuck-form" method="POST" accept-charset="utf-8">
{% csrf_token %}
<select name="character" required>
<option disabled selected value="">Selecciona un personaje</option>
{% for character in characters %}
<option value="{{ character }}">{{ character }}</option>
{% endfor %}
</select>
<br>
<button class="unstuck-button" type="submit" name="unstuck" data-id="Desbloquear">Desbloquear</button>
</form>
<hr>
<div class="alert-message" id="unstuck-response"></div>
</div>
</div>
</div>
</div>
</div>
</div>
+2
View File
@@ -26,6 +26,7 @@ urlpatterns = [
path('change-email/', views.change_email_view, name='change-email'), path('change-email/', views.change_email_view, name='change-email'),
path('confirm-old-email/', views.confirm_old_email_view, name='confirm-old-email'), path('confirm-old-email/', views.confirm_old_email_view, name='confirm-old-email'),
path('confirm-new-email/', views.confirm_new_email_view, name='confirm-new-email'), path('confirm-new-email/', views.confirm_new_email_view, name='confirm-new-email'),
path('expired-link/', views.expired_link_view, name='expired-link'),
path('promo-code/', views.promo_code_view, name='promo_code'), path('promo-code/', views.promo_code_view, name='promo_code'),
path('transfer-d-points/', views.transfer_d_points_view, name='transfer_d_points'), path('transfer-d-points/', views.transfer_d_points_view, name='transfer_d_points'),
path('rename-guild/', views.rename_guild_view, name='rename-guild'), path('rename-guild/', views.rename_guild_view, name='rename-guild'),
@@ -39,6 +40,7 @@ urlpatterns = [
path('activate-account', views.activate_account_view, name='activate_account'), path('activate-account', views.activate_account_view, name='activate_account'),
path('help', views.help_view, name='help'), path('help', views.help_view, name='help'),
path('novawow-players', views.novawow_players_view, name='novawow_players'), path('novawow-players', views.novawow_players_view, name='novawow_players'),
path('unstuck-character/', views.unstuck_character_view, name='unstuck-character'),
] ]
+82 -13
View File
@@ -5,12 +5,13 @@ import binascii
import os import os
import re import re
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.urls import reverse
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse
from django.db import connections from django.db import connections
from django.contrib import messages from django.contrib import messages
from django.contrib.auth import logout from django.contrib.auth import logout
from django import forms from django import forms
from .models import Noticia, ClienteCategoria, ServerSelection, RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, ClaimedReward, AccountActivation, SecurityToken, GuildRenameSettings, VoteSite, VoteLog, HomeApiPoints from .models import Noticia, ClienteCategoria, ServerSelection, RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, ClaimedReward, AccountActivation, SecurityToken, GuildRenameSettings, VoteSite, VoteLog, HomeApiPoints, UnstuckHistory
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
import logging import logging
from datetime import datetime, timedelta from datetime import datetime, timedelta
@@ -1001,22 +1002,22 @@ def change_email_view(request):
# Validar los campos # Validar los campos
if not all([current_password, current_email_input, new_email, conf_new_email, token]): if not all([current_password, current_email_input, new_email, conf_new_email, token]):
return JsonResponse({'success': False, 'message': 'Por favor, complete todos los campos.'}) return JsonResponse({'success': False, 'message': '<span class="red-form-response">Por favor, complete todos los campos.</span>'})
if current_email_input != current_email: if current_email_input != current_email:
return JsonResponse({'success': False, 'message': 'El correo actual no es correcto.'}) return JsonResponse({'success': False, 'message': '<span class="red-form-response">El correo actual no es correcto.</span>'})
if new_email != conf_new_email: if new_email != conf_new_email:
return JsonResponse({'success': False, 'message': 'Los correos no coinciden.'}) return JsonResponse({'success': False, 'message': '<span class="red-form-response">Los correos no coinciden.</span>'})
if not re.match(r'^[a-zA-Z0-9._%+-]+@gmail\.com$', new_email): if not re.match(r'^[a-zA-Z0-9._%+-]+@gmail\.com$', new_email):
return JsonResponse({'success': False, 'message': 'El nuevo correo no es válido.'}) return JsonResponse({'success': False, 'message': '<span class="red-form-response">El nuevo correo no es válido.</span>'})
if not security_token or security_token.token != token: if not security_token or security_token.token != token:
return JsonResponse({'success': False, 'message': 'Token de seguridad incorrecto.'}) return JsonResponse({'success': False, 'message': '<span class="red-form-response">Token de seguridad incorrecto.</span>'})
if not authenticate(username, current_password): if not authenticate(username, current_password):
return JsonResponse({'success': False, 'message': 'Contraseña incorrecta.'}) return JsonResponse({'success': False, 'message': '<span class="red-form-response">Contraseña incorrecta.</span>'})
# Generar hashes # Generar hashes
old_email_hash = secrets.token_urlsafe(16) old_email_hash = secrets.token_urlsafe(16)
@@ -1049,7 +1050,7 @@ def change_email_view(request):
context=context_old_email context=context_old_email
) )
return JsonResponse({'success': True, 'message': 'Se ha enviado un correo de confirmación al correo actual.'}) return JsonResponse({'success': True, 'message': '<span class="ok-form-response">Se ha enviado un correo de confirmación al correo actual.</span>'})
return render(request, 'account/change_email.html') return render(request, 'account/change_email.html')
@@ -1059,7 +1060,11 @@ def confirm_old_email_view(request):
activation = AccountActivation.objects.filter(old_email_hash=hash, is_used=False).first() activation = AccountActivation.objects.filter(old_email_hash=hash, is_used=False).first()
if not activation or activation.is_expired(): if not activation or activation.is_expired():
return HttpResponse('Enlace no válido o expirado.', status=400) return JsonResponse({
'success': False,
'message': '<span class="red-form-response">Enlace no válido o expirado.</span>',
'redirect_url': reverse('expired-link')
})
# Marcar solo el old_email_hash como usado # Marcar solo el old_email_hash como usado
activation.is_used = True activation.is_used = True
@@ -1079,15 +1084,18 @@ def confirm_old_email_view(request):
context=context_new_email context=context_new_email
) )
return HttpResponse('Correo confirmado. Se ha enviado un enlace al nuevo correo.') return JsonResponse({'success': True, 'message': '<span class="ok-form-response">Correo confirmado. Se ha enviado un enlace al nuevo correo.</span>'})
def confirm_new_email_view(request): def confirm_new_email_view(request):
hash = request.GET.get('hash') hash = request.GET.get('hash')
activation = AccountActivation.objects.filter(hash=hash, is_new_email_used=False).first() activation = AccountActivation.objects.filter(hash=hash, is_new_email_used=False).first()
if not activation or activation.is_expired(): if not activation or activation.is_expired():
return HttpResponse('Enlace no válido o expirado.', status=400) return JsonResponse({
'success': False,
'message': '<span class="red-form-response">Enlace no válido o expirado.</span>',
'redirect_url': reverse('expired-link')
})
# Marcar solo el new_email_hash como usado # Marcar solo el new_email_hash como usado
activation.is_new_email_used = True activation.is_new_email_used = True
@@ -1114,12 +1122,73 @@ def confirm_new_email_view(request):
context=context_old_email context=context_old_email
) )
return HttpResponse('El cambio de correo ha sido confirmado y completado con éxito.') return JsonResponse({'success': True, 'message': '<span class="ok-form-response">El cambio de correo ha sido confirmado y completado con éxito.</span>'})
def expired_link_view(request):
return render(request, 'account/expired_link.html')
def promo_code_view(request): def promo_code_view(request):
return render(request, 'account/promo_code.html') return render(request, 'account/promo_code.html')
from django.utils.timezone import now
from datetime import timedelta
def unstuck_character_view(request):
username = request.session.get('username')
if not username:
return redirect('login')
# Obtener personajes del usuario desde la base de datos `acore_characters`
with connections['acore_characters'].cursor() as cursor:
cursor.execute("""
SELECT name, online
FROM characters
WHERE account = (
SELECT id
FROM acore_auth.account
WHERE username = %s
)
""", [username])
characters_data = cursor.fetchall()
characters = {row[0]: row[1] for row in characters_data} # Diccionario con nombre y estado de conexión
if request.method == 'POST':
character_name = request.POST.get('character')
# Validar si el personaje fue seleccionado
if not character_name:
return JsonResponse({'success': False, 'message': '<span class="red-form-response">Por favor, seleccione un personaje.</span>'})
# Verificar si el personaje pertenece al usuario
if character_name not in characters:
return JsonResponse({'success': False, 'message': '<span class="red-form-response">No tienes permiso para desbloquear este personaje.</span>'})
# Verificar si el personaje está desconectado
if characters[character_name] == 1: # Si está conectado
return JsonResponse({'success': False, 'message': '<span class="red-form-response">El personaje debe estar desconectado para ser desbloqueado.</span>'})
# Verificar el historial de uso del comando
last_unstuck = UnstuckHistory.objects.filter(character_name=character_name).order_by('-used_at').first()
if last_unstuck and last_unstuck.used_at > now() - timedelta(hours=12):
return JsonResponse({'success': False, 'message': '<span class="red-form-response">El personaje solo puede desbloquearse una vez cada 12 horas.</span>'})
# Ejecutar el comando SOAP
command = f".unstuck {character_name} startzone"
response = execute_soap_command(command)
if response is None:
return JsonResponse({'success': False, 'message': '<span class="red-form-response">Error de comunicación con el servidor. Intente nuevamente más tarde.</span>'})
# Analizar la respuesta
if f"You are summoning {character_name} (offline)" in response:
# Registrar el uso del comando
UnstuckHistory.objects.create(character_name=character_name, used_at=now())
return JsonResponse({'success': True, 'message': f'<span class="ok-form-response">El personaje {character_name} ha sido desbloqueado con éxito.</span>'})
else:
return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Error: {response}</span>'})
return render(request, 'account/unstuck_character.html', {'characters': characters.keys()})
def transfer_d_points_view(request): def transfer_d_points_view(request):
# Renderizar la plantilla para la transferencia de puntos # Renderizar la plantilla para la transferencia de puntos
return render(request, 'account/transfer_d_points.html') return render(request, 'account/transfer_d_points.html')
Binary file not shown.
Binary file not shown.
-1
View File
@@ -27,7 +27,6 @@ DEBUG = True
ALLOWED_HOSTS = ['*'] ALLOWED_HOSTS = ['*']
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [