Skip to content

Commit

Permalink
Merge pull request #26 from Ajordat/tags
Browse files Browse the repository at this point in the history
Tags functionality for decks
  • Loading branch information
Ajordat authored Sep 3, 2024
2 parents 7c17d8b + 97886be commit 69011cc
Show file tree
Hide file tree
Showing 61 changed files with 2,203 additions and 987 deletions.
2 changes: 1 addition & 1 deletion alteredbuilder/api/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from rest_framework import routers

from . import views
from api import views

# Register the available views

Expand Down
10 changes: 5 additions & 5 deletions alteredbuilder/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from rest_framework.request import Request
from rest_framework.response import Response

from . import serializers as serial
from api.serializers import CardSerializer, GroupSerializer, UserSerializer
from decks.models import Card


Expand All @@ -14,7 +14,7 @@ class UserViewSet(viewsets.ModelViewSet):
"""

queryset = User.objects.all().order_by("-date_joined")
serializer_class = serial.UserSerializer
serializer_class = UserSerializer
permission_classes = [permissions.IsAdminUser]


Expand All @@ -24,7 +24,7 @@ class GroupViewSet(viewsets.ModelViewSet):
"""

queryset = Group.objects.all()
serializer_class = serial.GroupSerializer
serializer_class = GroupSerializer
permission_classes = [permissions.IsAdminUser]


Expand All @@ -42,7 +42,7 @@ class CardViewSet(AdminWriteOrAuthenticatedGetViewSet):
"""API endpoint that allows to view all the cards."""

queryset = Card.objects.all().order_by("reference")
serializer_class = serial.CardSerializer
serializer_class = CardSerializer

def retrieve(self, request: Request, pk=None) -> Response:
"""Retrieve the information of a card.
Expand All @@ -56,6 +56,6 @@ def retrieve(self, request: Request, pk=None) -> Response:
"""
card = get_object_or_404(Card, pk=pk)
context = {"request": request}
serializer = serial.CardSerializer(card, context=context)
serializer = CardSerializer(card, context=context)

return Response(serializer.data)
2 changes: 1 addition & 1 deletion alteredbuilder/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.10.1"
__version__ = "1.11.0"
2 changes: 1 addition & 1 deletion alteredbuilder/config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from django.views.generic import RedirectView, TemplateView
from django.views.i18n import JavaScriptCatalog

from .sitemaps import (
from config.sitemaps import (
DeckSitemap,
DailyLocalizedStaticViewSitemap,
MonthlyLocalizedStaticViewSitemap,
Expand Down
11 changes: 10 additions & 1 deletion alteredbuilder/decks/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.contrib import admin
from django.http import HttpRequest

from .models import (
from decks.models import (
Card,
CardInDeck,
Comment,
Expand All @@ -14,6 +14,7 @@
PrivateLink,
Set,
Subtype,
Tag,
)


Expand Down Expand Up @@ -69,6 +70,7 @@ class DeckAdmin(admin.ModelAdmin):
"comment_count",
"created_at",
"modified_at",
"tags",
]
fieldsets = [
(
Expand All @@ -79,6 +81,7 @@ class DeckAdmin(admin.ModelAdmin):
"name",
"description",
"hero",
"tags",
("created_at", "modified_at"),
]
},
Expand Down Expand Up @@ -255,3 +258,9 @@ def get_fieldsets(
lang_fieldset = (name, {"fields": [f"name_{code}"]})
fieldsets.append(lang_fieldset)
return fieldsets


@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
list_display = ["name", "type", "description"]
search_fields = ["name"]
8 changes: 5 additions & 3 deletions alteredbuilder/decks/deck_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,7 @@ def import_unique_card(reference) -> Card: # pragma: no cover
if "ECHO_EFFECT" in card_data["elements"]:
card_dict["echo_effect"] = card_data["elements"]["ECHO_EFFECT"]

card = Card.objects.create(**card_dict)
card.subtypes.add(*og_card.subtypes.all())
card = Card(**card_dict)

for language, _ in settings.LANGUAGES: # noqa: F402
if language == settings.LANGUAGE_CODE:
Expand All @@ -412,7 +411,10 @@ def import_unique_card(reference) -> Card: # pragma: no cover
if language not in IMAGE_ERROR_LOCALES:
card.image_url = card_data["imagePath"]

card.save()
with transaction.atomic():
card.save()
card.subtypes.add(*og_card.subtypes.all())

return card

else:
Expand Down
23 changes: 21 additions & 2 deletions alteredbuilder/decks/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.core.validators import RegexValidator
from django.utils.translation import gettext_lazy as _

from .models import Card, Comment, Deck
from decks.models import Card, Comment, Deck, Tag


class DecklistForm(forms.Form):
Expand Down Expand Up @@ -55,6 +55,23 @@ class DeckMetadataForm(forms.Form):
is_public = forms.BooleanField(required=False)


class DeckTagsForm(forms.Form):
"""Form to create or modify the Tags of a Deck."""

template_name = "forms/submit_deck_tags.html"

primary_tags = forms.ModelChoiceField(
queryset=Tag.objects.filter(type=Tag.Type.TYPE).order_by("pk"),
widget=forms.RadioSelect,
required=False,
)
secondary_tags = forms.ModelMultipleChoiceField(
queryset=Tag.objects.filter(type=Tag.Type.SUBTYPE),
widget=forms.CheckboxSelectMultiple,
required=False,
)


class CommentForm(forms.Form):
"""Form to create a Comment on a Deck."""

Expand All @@ -67,12 +84,14 @@ class CommentForm(forms.Form):


class CardImportForm(forms.Form):
"""Form to import a Card of unique rarity into the database."""

reference = forms.CharField(
label=_("Card Reference"),
max_length=Card._meta.get_field("reference").max_length,
validators=[
RegexValidator(
r"^ALT_[A-Z]{4,6}_(?:B|P)_[A-Z]{2}_\d{2}_U_\d+$",
r"^ALT_[A-Z]{4,6}_(?:B|P|A)_[A-Z]{2}_\d{2}_U_\d+$",
_(
"Invalid value. The reference should look similar to 'ALT_COREKS_B_OR_21_U_2139'."
),
Expand Down
2 changes: 1 addition & 1 deletion alteredbuilder/decks/game_modes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from django.utils.translation import gettext_lazy as _

from .models import Deck, Card
from decks.models import Deck, Card


class GameMode(ABC):
Expand Down
50 changes: 50 additions & 0 deletions alteredbuilder/decks/migrations/0059_tag_deck_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Generated by Django 5.0.8 on 2024-08-26 13:37

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("decks", "0058_card_created_at"),
]

operations = [
migrations.CreateModel(
name="Tag",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(unique=True)),
("description", models.CharField(blank=True)),
("description_de", models.CharField(blank=True, null=True)),
("description_en", models.CharField(blank=True, null=True)),
("description_es", models.CharField(blank=True, null=True)),
("description_fr", models.CharField(blank=True, null=True)),
("description_it", models.CharField(blank=True, null=True)),
(
"type",
models.CharField(
choices=[("TY", "type"), ("SU", "subtype")], max_length=2
),
),
],
options={
"ordering": ["-type", "name"],
},
),
migrations.AddField(
model_name="deck",
name="tags",
field=models.ManyToManyField(
blank=True, related_name="decks", to="decks.tag"
),
),
]
100 changes: 100 additions & 0 deletions alteredbuilder/decks/migrations/0060_create_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
from django.db import migrations


def init_models(apps):
global Tag
Tag = apps.get_model("decks", "Tag")


def delete_tags(apps, schema_editor):
init_models(apps)

Tag.objects.all().delete()


def create_tags(apps, schema_editor):
init_models(apps)

tags = []
data = [
{
"name": "Aggro",
"type": "TY",
"description_en": "Get an early lead and maintain pressure.",
"description_es": "Toma una ventaja temprana y mantén la presión.",
"description_fr": "Prenez une avance rapide et maintenez la pression.",
"description_it": "Ottieni un vantaggio iniziale e mantieni la pressione.",
"description_de": "Verschaffe dir frühzeitig einen Vorsprung und halte den Druck aufrecht.",
},
{
"name": "Midrange",
"type": "TY",
"description_en": "Balance early aggression with late-game stability.",
"description_es": "Equilibra la agresión temprana con estabilidad en el juego tardío.",
"description_fr": "Équilibrez l'agression précoce avec la stabilité en fin de partie.",
"description_it": "Bilancia l'aggressività iniziale con la stabilità a fine partita.",
"description_de": "Balanciere frühe Aggression mit Stabilität im späten Spiel.",
},
{
"name": "Control",
"type": "TY",
"description_en": "Aims to prolong the game and gain control for a late win.",
"description_es": "Busca prolongar el juego y ganar control para una victoria tardía.",
"description_fr": "Vise à prolonger la partie et à prendre le contrôle pour une victoire tardive.",
"description_it": "Mira a prolungare il gioco e ottenere il controllo per una vittoria tardiva.",
"description_de": "Zielt darauf ab, das Spiel zu verlängern und die Kontrolle zu übernehmen, um spät zu gewinnen.",
},
{
"name": "Combo",
"type": "SU",
"description_en": "Uses card combinations to achieve powerful effects.",
"description_es": "Utiliza combinaciones de cartas para lograr efectos poderosos.",
"description_fr": "Utilise des combinaisons de cartes pour obtenir des effets puissants.",
"description_it": "Utilizza combinazioni di carte per ottenere effetti potenti.",
"description_de": "Nutzt Kartenkombinationen, um mächtige Effekte zu erzielen.",
},
{
"name": "Token",
"type": "SU",
"description_en": "Focuses on generating and utilizing token creatures.",
"description_es": "Se centra en generar y utilizar criaturas de fichas.",
"description_fr": "Se concentre sur la génération et l'utilisation de créatures jetons.",
"description_it": "Si concentra sulla generazione e sull'utilizzo di creature token.",
"description_de": "Konzentriert sich auf die Erzeugung und Nutzung von Token-Kreaturen.",
},
{
"name": "Disruption",
"type": "SU",
"description_en": "Interferes with the opponent's strategy and resources.",
"description_es": "Interfiere con la estrategia y los recursos del oponente.",
"description_fr": "Interfère avec la stratégie et les ressources de l'adversaire.",
"description_it": "Interferisce con la strategia e le risorse dell'avversario.",
"description_de": "Stört die Strategie und Ressourcen des Gegners.",
},
{
"name": "Ramp",
"type": "SU",
"description_en": "Increases resources to play big cards faster.",
"description_es": "Aumenta los recursos para jugar cartas grandes más rápido.",
"description_fr": "Augmente les ressources pour jouer des grandes cartes plus rapidement.",
"description_it": "Aumenta le risorse per giocare carte grandi più velocemente.",
"description_de": "Erhöht Ressourcen, um größere Karten schneller zu spielen.",
},
]

for tag_data in data:

tags.append(Tag(**tag_data))

Tag.objects.bulk_create(tags)


class Migration(migrations.Migration):

dependencies = [
("decks", "0059_tag_deck_tags"),
]

operations = [
migrations.RunPython(code=create_tags, reverse_code=delete_tags),
]
17 changes: 17 additions & 0 deletions alteredbuilder/decks/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,22 @@ class Meta:
ordering = ["reference"]


class Tag(models.Model):
class Type(models.TextChoices):
TYPE = "TY", "type"
SUBTYPE = "SU", "subtype"

name = models.CharField(unique=True)
description = models.CharField(blank=True)
type = models.CharField(max_length=2, choices=Type)

def __str__(self) -> str:
return self.name

class Meta:
ordering = ["-type", "name"]


class Deck(models.Model, HitCountMixin):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
Expand All @@ -172,6 +188,7 @@ class Deck(models.Model, HitCountMixin):
object_id_field="object_pk",
related_query_name="hit_count_generic_relation",
)
tags = models.ManyToManyField(Tag, blank=True, related_name="decks")

modified_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
Expand Down
Loading

0 comments on commit 69011cc

Please sign in to comment.