-1

I'm learning django and in my project can't figure out how properly get and displayed elements from many to many relation on deck detail page.

model.py

class Card(models.Model):
    def upload_path(self, filename):
        return os.path.join('cards/', filename)

    image = models.ImageField(upload_to=upload_path)
    card_num = models.CharField(max_length=20, default='')
    name = models.CharField(max_length=500, default='')
    desc = models.TextField(max_length=500, default='')
    card_class = models.OneToOneField(CardClass, on_delete=models.DO_NOTHING, default='')
    cost = models.OneToOneField(Cost, on_delete=models.DO_NOTHING, default='')
    card_type = models.OneToOneField(CardType, on_delete=models.DO_NOTHING, default='')
    rarity = models.OneToOneField(Rarity, on_delete=models.DO_NOTHING, default='')
    resource = models.IntegerField(default=None)
    attack = models.IntegerField(default=None)
    defence = models.IntegerField(default=None)


    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('card:cardPageDetail', args=[self.name])


class Deck(models.Model):

    def upload_path(self, filename):
        return os.path.join('decks/', filename)

    image = models.ImageField(upload_to=upload_path)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    cards_list = models.ManyToManyField(Card, related_name='cards_list')
    deck_id = models.CharField(max_length=10, default='')
    name = models.CharField(max_length=500, default='')
    desc = models.CharField(max_length=500, default='')
    price = models.CharField(max_length=500, default='')

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('card:deckPageDetail', args=[self.name])

views.py

def deckPageDetail(request, name):
    deck=get_object_or_404(Deck, name=name)
    cards_all = Card.objects.all()
    queryset = cards_all.objects.filter(cards_list__in=deck.deck_id)
    print(queryset)
    context = {
        'deck': deck,
        'cards_in_deck': queryset,
    }
    return render(request, 'landing/deck_detail.html', context)

I tried few solutions based on stackoverflow and uncle google, but without results.I will be grateful for help.

Andrew
  • 1

2 Answers2

0

You just have to access the card_list attribute of your deck.

deck = Deck.objects.get(id=1)
for card in deck.cards_list.all():
    print(card)
Nicolas Appriou
  • 2,208
  • 19
  • 32
  • Hi, thank you for an answer. It is working for specific deck id. How I can change it to recognize in deck = Deck.objects.get(id=1) which deck is used and what id it has, and based on that displayed list of cards. It's probably a newbie question, but I'm just learning. Thanks :) – Andrew Nov 17 '20 at 11:15
0

You already have the deck with the M2M so you can access the card list directly in the template. First, let's clean up the code that isn't required.

def deckPageDetail(request, name):
    deck=get_object_or_404(Deck, name=name)
    context = {
        'deck': deck,
    }
    return render(request, 'landing/deck_detail.html', context)

Then inside of your landing/deck_detail.html template you can loop over the cards with the code below.

{% for card in deck.cards_list.all %}
    {{ card }}
{% endfor %}

and if you want to access the cards information

{% for card in deck.cards_list.all %}
    {{ card }} {{ card.image.url }} {{ card.card_num }}
{% endfor %}

and just in case you wanted it in the view

def deckPageDetail(request, name):
    deck=get_object_or_404(Deck, name=name)
    queryset = deck.cards_list.all()
    print(queryset)
    context = {
        'deck': deck,
        'cards_in_deck': queryset,
    }
    return render(request, 'landing/deck_detail.html', context)
Lemon.py
  • 819
  • 10
  • 22