Search code examples
djangomany-to-manydjango-ormmanytomanyfield

Displaying ManyToManyField in django template


I've been trying to display the exact values of model with ManyToMany relation but I just couldn't, all what I've achevied is receiving QuerySet

<QuerySet [<Stack: PHP>, <Stack: js>]> 

by adding to template tags

{{ brand.technologies.all }}

But I would like to receive and display 2 fields, name and icon. I've tried with some loops like

  {% for brand in brands %}
      {% for technologies in brand.technologies.all %} {{ technologies.name }} {{ technologies.icon }} {% endfor %}
  {% endfor %}

but it doesn't give any results. There is not problem with syntax because page is displaying and looks like this

image

models.py

STACK = (
        ('PHP', 'PHP'),
        ('js', 'JavaScript'),
        ...
    )

STACK_ICONS = (
        ('/static/icons/stack/php.png', 'PHP'),
        ('/static/icons/stack/javascript.png', 'JavaScript'),
        ...
    )

class Company(models.Model):
    name = models.CharField(max_length=100, blank=False)
    students = models.CharField(max_length=3, choices=STUDENTS)
    type = models.CharField(max_length=15, choices=TYPES)
    workers = models.PositiveIntegerField(validators=[MinValueValidator(1)])
    city = models.CharField(max_length=15,choices=CITIES)
    company_about = models.TextField(max_length=500, blank=False)   
    slug = models.SlugField(unique=True)
    icon = models.ImageField(blank=True, null=True)
    image = models.ImageField(blank=True, null=True)
    logo = models.ImageField(blank=True, null=True)
    technologies = models.ManyToManyField('Stack')

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Company, self).save(*args, **kwargs)

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.name

# object stack relation manytomany with Company

class Stack(models.Model):
    name = models.CharField(max_length=30, choices=STACK)
    icon = models.CharField(max_length=80, choices=STACK_ICONS)

    def __str__(self):
        return self.name

views.py

from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
...

def comp_list(request):
    f = CompanyFilter(request.GET, queryset=Company.objects.all())
    return render(request, 'company/comp_list.html', {'filter': f})

def companies(request):
    company = get_object_or_404(Company)
    return render(request, 'company/comp_list.html', {'company': company})

def home(request):
    return render(request, 'company/home.html')

def brands(request, slug):
    brand = get_object_or_404(Company, slug=slug)
    return render(request, 'company/comp_view.html', {'brand': brand})

def stacks(request):
    stack = get_object_or_404(Stack)
    return render(request, 'company/comp_view.html', {'stack': stack})

comp_view.html

{% extends 'company/base.html' %}

{% block content %}
<div class="row company-details">
    <div class="col col-md-2"></div>
    <div class="col col-md-8">
    <input class="btn btn-success" type="button" value="Go Back" onclick="history.back(-1)" />
    <div class="col col-md-12 company-bg" style="background-image: url('{{ brand.image.url }}'); background-repeat: no-repeat, repeat;">
    </div>
    <div class="bottom-overlay"></div>
    <div class="company-description">
        <div class="heading">
            <div class="title">About us</div>
            <div class="social-media">
                <a href="">Facebook</a>
            </div>
        </div>
        <div class="company-about">
            {{ brand.company_about }}
        </div>



    </div>
    <div class="company-stats">
        <div class="company-logo-container">
            <img class="company-logo" src="{{ brand.logo.url }}">
        </div>
        <div class="company-attributes">
            <div class="field-group">
                <div class="field">Type</div>
                <div class="value">{{ brand.type }}</div>
            </div>
            <div class="field-group">
                <div class="field">Company size</div>
                <div class="value">{{ brand.workers }}+</div>
            </div>
            <div class="field-group">
                <div class="field">Headquarters</div>
                <div class="value">{{ brand.city }}</div>
            </div>
            <div class="field-group">
                <div class="field">Open for students</div>
                <div class="value">{{ brand.students }}</div>
            </div>
        </div>
        <div class="technologies-section">
            <p class="tech-heading">Technologies</p>
            <div class="technologies-wrapper">
                {{ brand.technologies.all }}
                {% for brand in brands %}
                    {% for technologies in brand.technologies.all %} {{ technologies.name }} {% endfor %}
                {% endfor %}

            </div>
        </div>
    </div>
    <div class="col col-md-2"></div>
</div>

{% endblock %}

Solution

  • I don't understand why you've suddenly added an outer loop through brands. You don't have anything called brands, and you're successfully accessing all the other data via brand. Just continue to do so, and drop the outer loop.

    <div class="technologies-wrapper">
        {% for technologies in brand.technologies.all %} {{ technologies.name }} {% endfor %}
    </div>