Divide home/models.py en el paquete home/models/ por secciones
El módulo (~310 líneas, 30 modelos) se convierte en un paquete cuyo __init__.py re-exporta todos los modelos, de modo que `from home.models import X`, el admin y el resto de consumidores siguen funcionando igual. Módulos por sección: pricing (precios/costes de servicios + GuildRenameSettings), store (Category, Item, StripeLog, Pedido), site (contenido/config del sitio), recruit, accounts (activación, token de seguridad, LoginAttempt), voting (VoteSite, VoteLog, HomeApiPoints) e history. Las claves foráneas por clase directa quedan en el mismo módulo; cada submódulo importa solo lo que usa. Se eliminan imports de cabecera muertos (ValidationError, uuid, secrets) y las líneas de import duplicadas del original. Migración-neutral: `makemigrations home --dry-run` -> "No changes detected" (app_label=home y nombres/tablas de modelo intactos). Definición de cada modelo idéntica (extracción por AST). `manage.py check` sin incidencias. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
-313
@@ -1,313 +0,0 @@
|
|||||||
# home/models.py
|
|
||||||
from django.db import models
|
|
||||||
from django_ckeditor_5.fields import CKEditor5Field
|
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
from django.utils import timezone
|
|
||||||
import uuid
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
import secrets
|
|
||||||
|
|
||||||
class Noticia(models.Model):
|
|
||||||
titulo = models.CharField(max_length=200)
|
|
||||||
contenido = CKEditor5Field('Contenido', config_name='default')
|
|
||||||
fecha_publicacion = models.DateTimeField(auto_now=True) # Cambiado a DateTimeField
|
|
||||||
fecha_fin_evento = models.DateField(null=True, blank=True)
|
|
||||||
enlace = models.URLField(max_length=200, blank=True, null=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.titulo
|
|
||||||
|
|
||||||
class MaintenanceMode(models.Model):
|
|
||||||
is_active = models.BooleanField(default=False)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "Maintenance Mode"
|
|
||||||
|
|
||||||
class UnstuckHistory(models.Model):
|
|
||||||
character_name = models.CharField(max_length=50)
|
|
||||||
used_at = models.DateTimeField()
|
|
||||||
|
|
||||||
class ReviveHistory(models.Model):
|
|
||||||
character_name = models.CharField(max_length=50)
|
|
||||||
used_at = models.DateTimeField()
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.character_name} - {self.used_at}"
|
|
||||||
|
|
||||||
class ChangeFactionPrice(models.Model):
|
|
||||||
price = models.DecimalField(max_digits=6, decimal_places=2, default=10.00)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Precio para cambiar facción: {self.price} EUR"
|
|
||||||
|
|
||||||
|
|
||||||
class LevelUpPrice(models.Model):
|
|
||||||
price = models.DecimalField(max_digits=10, decimal_places=2, default=10.00)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Subir a nivel 80: {self.price} EUR"
|
|
||||||
|
|
||||||
|
|
||||||
class GoldPrice(models.Model):
|
|
||||||
gold_amount = models.IntegerField() # Cantidad de oro
|
|
||||||
price = models.DecimalField(max_digits=10, decimal_places=2) # Precio en EUR
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.gold_amount} oro - {self.price} EUR"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TransferPrice(models.Model):
|
|
||||||
price = models.DecimalField(max_digits=5, decimal_places=2)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Precio de transferencia: {self.price} EUR"
|
|
||||||
|
|
||||||
|
|
||||||
class Category(models.Model):
|
|
||||||
name = models.CharField(max_length=100, unique=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
|
|
||||||
class Item(models.Model):
|
|
||||||
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="items")
|
|
||||||
name = models.CharField(max_length=200)
|
|
||||||
price = models.DecimalField(max_digits=10, decimal_places=2) # Precio en euros
|
|
||||||
item_id = models.IntegerField(unique=True) # ID del ítem en el juego
|
|
||||||
image_url = models.URLField() # URL de la imagen del ítem
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
class RenamePrice(models.Model):
|
|
||||||
price = models.DecimalField(max_digits=5, decimal_places=2, default=2.00)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.price} EUR"
|
|
||||||
|
|
||||||
|
|
||||||
class CustomizePrice(models.Model):
|
|
||||||
price = models.DecimalField(max_digits=5, decimal_places=2, default=1.00)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.price} EUR"
|
|
||||||
|
|
||||||
|
|
||||||
class ChangeRacePrice(models.Model):
|
|
||||||
price = models.DecimalField(max_digits=5, decimal_places=2)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Cambiar raza: {self.price} EUR"
|
|
||||||
|
|
||||||
|
|
||||||
class ClienteCategoria(models.Model):
|
|
||||||
nombre = models.CharField(max_length=100)
|
|
||||||
descripcion = models.CharField(max_length=200, blank=True, null=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.nombre
|
|
||||||
|
|
||||||
|
|
||||||
class SistemaOperativo(models.Model):
|
|
||||||
categoria = models.ForeignKey(ClienteCategoria, related_name='sistemas_operativos', on_delete=models.CASCADE)
|
|
||||||
nombre = models.CharField(max_length=100)
|
|
||||||
url_descarga = models.URLField()
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.nombre} - {self.categoria.nombre}"
|
|
||||||
|
|
||||||
|
|
||||||
class ServerSelection(models.Model):
|
|
||||||
server_id = models.IntegerField()
|
|
||||||
name = models.CharField(max_length=100)
|
|
||||||
address = models.CharField(max_length=100)
|
|
||||||
port = models.IntegerField()
|
|
||||||
gamebuild = models.IntegerField()
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
expansion = 'WotLK' if self.gamebuild == 12340 else 'Cataclysm' if self.gamebuild == 15595 else 'Unknown'
|
|
||||||
return f"{self.name} ({expansion})"
|
|
||||||
|
|
||||||
|
|
||||||
class RecruitAFriend(models.Model):
|
|
||||||
title = models.CharField(max_length=255, default="Recluta a un amigo")
|
|
||||||
information = models.CharField(max_length=255, default="Información")
|
|
||||||
content = CKEditor5Field('Contenido', config_name='default')
|
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.title
|
|
||||||
|
|
||||||
|
|
||||||
class DownloadClientPage(models.Model):
|
|
||||||
title = models.CharField(max_length=255, default="Descarga del cliente")
|
|
||||||
content = CKEditor5Field('Contenido', config_name='default')
|
|
||||||
mac_instructions = CKEditor5Field('Instrucciones para macOS', blank=True, null=True, config_name='default')
|
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.title
|
|
||||||
|
|
||||||
|
|
||||||
class ContentCreator(models.Model):
|
|
||||||
title = models.CharField(max_length=200)
|
|
||||||
description = CKEditor5Field('Descripción', config_name='default')
|
|
||||||
content_type = models.CharField(max_length=60, default="Contenido general")
|
|
||||||
subtitle = models.CharField(max_length=60, default="Nova WoW")
|
|
||||||
youtube_video_url = models.URLField(max_length=300, blank=True, null=True)
|
|
||||||
avatar_image_url = models.URLField(max_length=300, blank=True, null=True)
|
|
||||||
youtube_channel_url = models.URLField(max_length=300, blank=True, null=True)
|
|
||||||
facebook_page_url = models.URLField(max_length=300, blank=True, null=True)
|
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.titles
|
|
||||||
|
|
||||||
class RecruitReward(models.Model):
|
|
||||||
required_friends = models.IntegerField()
|
|
||||||
reward_name = models.CharField(max_length=100)
|
|
||||||
item_id = models.IntegerField()
|
|
||||||
item_quantity = models.IntegerField(default=1)
|
|
||||||
item_link = models.URLField()
|
|
||||||
icon_class = models.CharField(max_length=50, help_text="Clase CSS para el icono (ej. 'icontinyl q3')")
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.required_friends} amigos - {self.reward_name}"
|
|
||||||
|
|
||||||
class ClaimedReward(models.Model):
|
|
||||||
recruit_reward = models.ForeignKey(RecruitReward, on_delete=models.CASCADE, related_name='claimed_rewards')
|
|
||||||
account_id = models.IntegerField()
|
|
||||||
character_name = models.CharField(max_length=100)
|
|
||||||
username = models.CharField(max_length=100)
|
|
||||||
claimed_at = models.DateTimeField(auto_now_add=True)
|
|
||||||
ip_address = models.CharField(max_length=45, default='127.0.0.1') # Añadir un valor predeterminado
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.username} - {self.recruit_reward.reward_name} - {self.claimed_at}"
|
|
||||||
|
|
||||||
from django.db import models
|
|
||||||
from django.utils import timezone
|
|
||||||
|
|
||||||
from django.db import models
|
|
||||||
from django.utils import timezone
|
|
||||||
|
|
||||||
class AccountActivation(models.Model):
|
|
||||||
# En 3.4.3 (Battle.net) la identidad es el email; el username de la cuenta
|
|
||||||
# de juego se genera al activar (<bnetId>#1), por eso es opcional aquí.
|
|
||||||
username = models.CharField(max_length=17, null=True, blank=True)
|
|
||||||
email = models.EmailField()
|
|
||||||
old_email = models.EmailField(null=True, blank=True)
|
|
||||||
password = models.CharField(max_length=64)
|
|
||||||
# salt/verifier ya no se precalculan en el registro (se calculan al activar,
|
|
||||||
# tanto el de bnet como el de la cuenta de juego). Se conservan opcionales
|
|
||||||
# por compatibilidad con el flujo de cambio de email.
|
|
||||||
salt = models.BinaryField(max_length=32, null=True, blank=True)
|
|
||||||
verifier = models.BinaryField(max_length=256, null=True, blank=True)
|
|
||||||
recruiter_id = models.IntegerField(null=True, blank=True)
|
|
||||||
hash = models.CharField(max_length=32, unique=True)
|
|
||||||
old_email_hash = models.CharField(max_length=32, null=True, blank=True)
|
|
||||||
is_used = models.BooleanField(default=False) # Indica si el old_email_hash ha sido usado
|
|
||||||
is_new_email_used = models.BooleanField(default=False) # Indica si el hash del nuevo correo ha sido usado
|
|
||||||
created_at = models.DateTimeField(default=timezone.now)
|
|
||||||
|
|
||||||
def is_expired(self):
|
|
||||||
return timezone.now() > self.created_at + timezone.timedelta(hours=1)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Activation for {self.username}"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SecurityToken(models.Model):
|
|
||||||
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
|
|
||||||
token = models.CharField(max_length=6)
|
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
|
||||||
expires_at = models.DateTimeField()
|
|
||||||
ip_address = models.GenericIPAddressField()
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Token for {self.user.username if self.user else 'Desconocido'}"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class GuildRenameSettings(models.Model):
|
|
||||||
cost = models.DecimalField(max_digits=10, decimal_places=2, default=10, help_text="Costo en euros para renombrar una hermandad.")
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Configuración de renombrar hermandad - Costo: {self.cost} €"
|
|
||||||
|
|
||||||
|
|
||||||
class VoteSite(models.Model):
|
|
||||||
name = models.CharField(max_length=100, unique=True)
|
|
||||||
url = models.URLField(max_length=200, help_text="URL del sitio de votación")
|
|
||||||
image_url = models.URLField(max_length=300, help_text="URL completa de la imagen")
|
|
||||||
points = models.IntegerField(default=1, help_text="Puntos otorgados por votar")
|
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
class VoteLog(models.Model):
|
|
||||||
account_id = models.IntegerField()
|
|
||||||
vote_site = models.ForeignKey('VoteSite', on_delete=models.CASCADE)
|
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
|
||||||
last_vote_time = models.DateTimeField(null=True, blank=True)
|
|
||||||
processed = models.BooleanField(default=False)
|
|
||||||
processed_at = models.DateTimeField(null=True, blank=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Voto para {self.vote_site.name} por cuenta {self.account_id}"
|
|
||||||
|
|
||||||
|
|
||||||
class HomeApiPoints(models.Model):
|
|
||||||
accountID = models.IntegerField(unique=True)
|
|
||||||
vp = models.IntegerField(default=0)
|
|
||||||
dp = models.IntegerField(default=0)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
db_table = 'home_api_points'
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Cuenta {self.accountID} - PV: {self.vp}, DP: {self.dp}"
|
|
||||||
|
|
||||||
class LoginAttempt(models.Model):
|
|
||||||
username = models.CharField(max_length=100)
|
|
||||||
status = models.CharField(max_length=50) # Ejemplo: 'Éxito' o 'Fracaso'
|
|
||||||
ip_address = models.GenericIPAddressField() # IP del intento de inicio de sesión
|
|
||||||
timestamp = models.DateTimeField(auto_now_add=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.username} - {self.status} - {self.timestamp}"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class StripeLog(models.Model):
|
|
||||||
account_id = models.IntegerField() # ID de la cuenta en acore_auth
|
|
||||||
username = models.CharField(max_length=100) # Nombre de la cuenta
|
|
||||||
email = models.EmailField() # Correo electrónico
|
|
||||||
acore_ip = models.GenericIPAddressField() # IP de acore_auth
|
|
||||||
stripe_ip = models.GenericIPAddressField(blank=True, null=True) # IP detectada por Stripe
|
|
||||||
product_name = models.TextField() # Producto comprado
|
|
||||||
amount = models.DecimalField(max_digits=10, decimal_places=2) # Precio total
|
|
||||||
session_id = models.CharField(max_length=255) # ID de la sesión de Stripe
|
|
||||||
mode = models.CharField(max_length=10, choices=[("test", "Test"), ("live", "Live")]) # Modo de Stripe
|
|
||||||
character_name = models.CharField(max_length=100) # Nombre del personaje que compró
|
|
||||||
timestamp = models.DateTimeField(auto_now_add=True) # Fecha y hora
|
|
||||||
fulfilled = models.BooleanField(default=False) # Si la entrega ya se procesó (evita re-entregas)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.username} compró {self.product_name} por {self.amount}€ ({self.mode})"
|
|
||||||
|
|
||||||
|
|
||||||
class Pedido(models.Model):
|
|
||||||
transaction_id = models.CharField(max_length=100, unique=True, null=True, blank=True)
|
|
||||||
email_cliente = models.EmailField()
|
|
||||||
estado = models.CharField(max_length=20, default="Pendiente")
|
|
||||||
monto = models.DecimalField(max_digits=10, decimal_places=2)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Pedido {self.transaction_id} - {self.estado}"
|
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
"""Modelos de la app `home`, divididos por secciones.
|
||||||
|
|
||||||
|
Antes un único home/models.py. El `import *` de cada submódulo re-exporta
|
||||||
|
los modelos para que `from home.models import X`, el admin y las migraciones
|
||||||
|
(app_label=`home`, nombres de modelo intactos) sigan funcionando igual.
|
||||||
|
"""
|
||||||
|
from .pricing import * # noqa: F401,F403
|
||||||
|
from .store import * # noqa: F401,F403
|
||||||
|
from .site import * # noqa: F401,F403
|
||||||
|
from .recruit import * # noqa: F401,F403
|
||||||
|
from .accounts import * # noqa: F401,F403
|
||||||
|
from .voting import * # noqa: F401,F403
|
||||||
|
from .history import * # noqa: F401,F403
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
from django.db import models
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
|
class AccountActivation(models.Model):
|
||||||
|
# En 3.4.3 (Battle.net) la identidad es el email; el username de la cuenta
|
||||||
|
# de juego se genera al activar (<bnetId>#1), por eso es opcional aquí.
|
||||||
|
username = models.CharField(max_length=17, null=True, blank=True)
|
||||||
|
email = models.EmailField()
|
||||||
|
old_email = models.EmailField(null=True, blank=True)
|
||||||
|
password = models.CharField(max_length=64)
|
||||||
|
# salt/verifier ya no se precalculan en el registro (se calculan al activar,
|
||||||
|
# tanto el de bnet como el de la cuenta de juego). Se conservan opcionales
|
||||||
|
# por compatibilidad con el flujo de cambio de email.
|
||||||
|
salt = models.BinaryField(max_length=32, null=True, blank=True)
|
||||||
|
verifier = models.BinaryField(max_length=256, null=True, blank=True)
|
||||||
|
recruiter_id = models.IntegerField(null=True, blank=True)
|
||||||
|
hash = models.CharField(max_length=32, unique=True)
|
||||||
|
old_email_hash = models.CharField(max_length=32, null=True, blank=True)
|
||||||
|
is_used = models.BooleanField(default=False) # Indica si el old_email_hash ha sido usado
|
||||||
|
is_new_email_used = models.BooleanField(default=False) # Indica si el hash del nuevo correo ha sido usado
|
||||||
|
created_at = models.DateTimeField(default=timezone.now)
|
||||||
|
|
||||||
|
def is_expired(self):
|
||||||
|
return timezone.now() > self.created_at + timezone.timedelta(hours=1)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Activation for {self.username}"
|
||||||
|
|
||||||
|
class SecurityToken(models.Model):
|
||||||
|
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
token = models.CharField(max_length=6)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
expires_at = models.DateTimeField()
|
||||||
|
ip_address = models.GenericIPAddressField()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Token for {self.user.username if self.user else 'Desconocido'}"
|
||||||
|
|
||||||
|
class LoginAttempt(models.Model):
|
||||||
|
username = models.CharField(max_length=100)
|
||||||
|
status = models.CharField(max_length=50) # Ejemplo: 'Éxito' o 'Fracaso'
|
||||||
|
ip_address = models.GenericIPAddressField() # IP del intento de inicio de sesión
|
||||||
|
timestamp = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.username} - {self.status} - {self.timestamp}"
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class UnstuckHistory(models.Model):
|
||||||
|
character_name = models.CharField(max_length=50)
|
||||||
|
used_at = models.DateTimeField()
|
||||||
|
|
||||||
|
class ReviveHistory(models.Model):
|
||||||
|
character_name = models.CharField(max_length=50)
|
||||||
|
used_at = models.DateTimeField()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.character_name} - {self.used_at}"
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class ChangeFactionPrice(models.Model):
|
||||||
|
price = models.DecimalField(max_digits=6, decimal_places=2, default=10.00)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Precio para cambiar facción: {self.price} EUR"
|
||||||
|
|
||||||
|
class LevelUpPrice(models.Model):
|
||||||
|
price = models.DecimalField(max_digits=10, decimal_places=2, default=10.00)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Subir a nivel 80: {self.price} EUR"
|
||||||
|
|
||||||
|
class GoldPrice(models.Model):
|
||||||
|
gold_amount = models.IntegerField() # Cantidad de oro
|
||||||
|
price = models.DecimalField(max_digits=10, decimal_places=2) # Precio en EUR
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.gold_amount} oro - {self.price} EUR"
|
||||||
|
|
||||||
|
class TransferPrice(models.Model):
|
||||||
|
price = models.DecimalField(max_digits=5, decimal_places=2)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Precio de transferencia: {self.price} EUR"
|
||||||
|
|
||||||
|
class RenamePrice(models.Model):
|
||||||
|
price = models.DecimalField(max_digits=5, decimal_places=2, default=2.00)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.price} EUR"
|
||||||
|
|
||||||
|
class CustomizePrice(models.Model):
|
||||||
|
price = models.DecimalField(max_digits=5, decimal_places=2, default=1.00)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.price} EUR"
|
||||||
|
|
||||||
|
class ChangeRacePrice(models.Model):
|
||||||
|
price = models.DecimalField(max_digits=5, decimal_places=2)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Cambiar raza: {self.price} EUR"
|
||||||
|
|
||||||
|
class GuildRenameSettings(models.Model):
|
||||||
|
cost = models.DecimalField(max_digits=10, decimal_places=2, default=10, help_text="Costo en euros para renombrar una hermandad.")
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Configuración de renombrar hermandad - Costo: {self.cost} €"
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
from django.db import models
|
||||||
|
from django_ckeditor_5.fields import CKEditor5Field
|
||||||
|
|
||||||
|
|
||||||
|
class RecruitAFriend(models.Model):
|
||||||
|
title = models.CharField(max_length=255, default="Recluta a un amigo")
|
||||||
|
information = models.CharField(max_length=255, default="Información")
|
||||||
|
content = CKEditor5Field('Contenido', config_name='default')
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.title
|
||||||
|
|
||||||
|
class RecruitReward(models.Model):
|
||||||
|
required_friends = models.IntegerField()
|
||||||
|
reward_name = models.CharField(max_length=100)
|
||||||
|
item_id = models.IntegerField()
|
||||||
|
item_quantity = models.IntegerField(default=1)
|
||||||
|
item_link = models.URLField()
|
||||||
|
icon_class = models.CharField(max_length=50, help_text="Clase CSS para el icono (ej. 'icontinyl q3')")
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.required_friends} amigos - {self.reward_name}"
|
||||||
|
|
||||||
|
class ClaimedReward(models.Model):
|
||||||
|
recruit_reward = models.ForeignKey(RecruitReward, on_delete=models.CASCADE, related_name='claimed_rewards')
|
||||||
|
account_id = models.IntegerField()
|
||||||
|
character_name = models.CharField(max_length=100)
|
||||||
|
username = models.CharField(max_length=100)
|
||||||
|
claimed_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
ip_address = models.CharField(max_length=45, default='127.0.0.1') # Añadir un valor predeterminado
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.username} - {self.recruit_reward.reward_name} - {self.claimed_at}"
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
from django.db import models
|
||||||
|
from django_ckeditor_5.fields import CKEditor5Field
|
||||||
|
|
||||||
|
|
||||||
|
class Noticia(models.Model):
|
||||||
|
titulo = models.CharField(max_length=200)
|
||||||
|
contenido = CKEditor5Field('Contenido', config_name='default')
|
||||||
|
fecha_publicacion = models.DateTimeField(auto_now=True) # Cambiado a DateTimeField
|
||||||
|
fecha_fin_evento = models.DateField(null=True, blank=True)
|
||||||
|
enlace = models.URLField(max_length=200, blank=True, null=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.titulo
|
||||||
|
|
||||||
|
class MaintenanceMode(models.Model):
|
||||||
|
is_active = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "Maintenance Mode"
|
||||||
|
|
||||||
|
class ClienteCategoria(models.Model):
|
||||||
|
nombre = models.CharField(max_length=100)
|
||||||
|
descripcion = models.CharField(max_length=200, blank=True, null=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.nombre
|
||||||
|
|
||||||
|
class SistemaOperativo(models.Model):
|
||||||
|
categoria = models.ForeignKey(ClienteCategoria, related_name='sistemas_operativos', on_delete=models.CASCADE)
|
||||||
|
nombre = models.CharField(max_length=100)
|
||||||
|
url_descarga = models.URLField()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.nombre} - {self.categoria.nombre}"
|
||||||
|
|
||||||
|
class ServerSelection(models.Model):
|
||||||
|
server_id = models.IntegerField()
|
||||||
|
name = models.CharField(max_length=100)
|
||||||
|
address = models.CharField(max_length=100)
|
||||||
|
port = models.IntegerField()
|
||||||
|
gamebuild = models.IntegerField()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
expansion = 'WotLK' if self.gamebuild == 12340 else 'Cataclysm' if self.gamebuild == 15595 else 'Unknown'
|
||||||
|
return f"{self.name} ({expansion})"
|
||||||
|
|
||||||
|
class DownloadClientPage(models.Model):
|
||||||
|
title = models.CharField(max_length=255, default="Descarga del cliente")
|
||||||
|
content = CKEditor5Field('Contenido', config_name='default')
|
||||||
|
mac_instructions = CKEditor5Field('Instrucciones para macOS', blank=True, null=True, config_name='default')
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.title
|
||||||
|
|
||||||
|
class ContentCreator(models.Model):
|
||||||
|
title = models.CharField(max_length=200)
|
||||||
|
description = CKEditor5Field('Descripción', config_name='default')
|
||||||
|
content_type = models.CharField(max_length=60, default="Contenido general")
|
||||||
|
subtitle = models.CharField(max_length=60, default="Nova WoW")
|
||||||
|
youtube_video_url = models.URLField(max_length=300, blank=True, null=True)
|
||||||
|
avatar_image_url = models.URLField(max_length=300, blank=True, null=True)
|
||||||
|
youtube_channel_url = models.URLField(max_length=300, blank=True, null=True)
|
||||||
|
facebook_page_url = models.URLField(max_length=300, blank=True, null=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.titles
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Category(models.Model):
|
||||||
|
name = models.CharField(max_length=100, unique=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Item(models.Model):
|
||||||
|
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="items")
|
||||||
|
name = models.CharField(max_length=200)
|
||||||
|
price = models.DecimalField(max_digits=10, decimal_places=2) # Precio en euros
|
||||||
|
item_id = models.IntegerField(unique=True) # ID del ítem en el juego
|
||||||
|
image_url = models.URLField() # URL de la imagen del ítem
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class StripeLog(models.Model):
|
||||||
|
account_id = models.IntegerField() # ID de la cuenta en acore_auth
|
||||||
|
username = models.CharField(max_length=100) # Nombre de la cuenta
|
||||||
|
email = models.EmailField() # Correo electrónico
|
||||||
|
acore_ip = models.GenericIPAddressField() # IP de acore_auth
|
||||||
|
stripe_ip = models.GenericIPAddressField(blank=True, null=True) # IP detectada por Stripe
|
||||||
|
product_name = models.TextField() # Producto comprado
|
||||||
|
amount = models.DecimalField(max_digits=10, decimal_places=2) # Precio total
|
||||||
|
session_id = models.CharField(max_length=255) # ID de la sesión de Stripe
|
||||||
|
mode = models.CharField(max_length=10, choices=[("test", "Test"), ("live", "Live")]) # Modo de Stripe
|
||||||
|
character_name = models.CharField(max_length=100) # Nombre del personaje que compró
|
||||||
|
timestamp = models.DateTimeField(auto_now_add=True) # Fecha y hora
|
||||||
|
fulfilled = models.BooleanField(default=False) # Si la entrega ya se procesó (evita re-entregas)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.username} compró {self.product_name} por {self.amount}€ ({self.mode})"
|
||||||
|
|
||||||
|
class Pedido(models.Model):
|
||||||
|
transaction_id = models.CharField(max_length=100, unique=True, null=True, blank=True)
|
||||||
|
email_cliente = models.EmailField()
|
||||||
|
estado = models.CharField(max_length=20, default="Pendiente")
|
||||||
|
monto = models.DecimalField(max_digits=10, decimal_places=2)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Pedido {self.transaction_id} - {self.estado}"
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class VoteSite(models.Model):
|
||||||
|
name = models.CharField(max_length=100, unique=True)
|
||||||
|
url = models.URLField(max_length=200, help_text="URL del sitio de votación")
|
||||||
|
image_url = models.URLField(max_length=300, help_text="URL completa de la imagen")
|
||||||
|
points = models.IntegerField(default=1, help_text="Puntos otorgados por votar")
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class VoteLog(models.Model):
|
||||||
|
account_id = models.IntegerField()
|
||||||
|
vote_site = models.ForeignKey('VoteSite', on_delete=models.CASCADE)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
last_vote_time = models.DateTimeField(null=True, blank=True)
|
||||||
|
processed = models.BooleanField(default=False)
|
||||||
|
processed_at = models.DateTimeField(null=True, blank=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Voto para {self.vote_site.name} por cuenta {self.account_id}"
|
||||||
|
|
||||||
|
class HomeApiPoints(models.Model):
|
||||||
|
accountID = models.IntegerField(unique=True)
|
||||||
|
vp = models.IntegerField(default=0)
|
||||||
|
dp = models.IntegerField(default=0)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'home_api_points'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Cuenta {self.accountID} - PV: {self.vp}, DP: {self.dp}"
|
||||||
Reference in New Issue
Block a user