Search code examples
djangotemplatesmany-to-many

Can't render attributes of an objecte linked with M2M field


Trying to render attributes of objects that are linked with another object via m2m field.

#models

class Arm(models.Model):
    cmrs = models.ManyToManyField(CMR, null=True)


class CMR(models.Model):
    client = models.ForeignKey('Client', on_delete=models.CASCADE, 
    null=True, default="", blank=True)

The view

if us.groups.filter(name__in = ['prime']):
            query_set = Plan.objects.order_by('-pk')
            query_ys = Arm.objects.filter(date=ys)
            query_rn = Arm.objects.filter(date=rn)
            query_tm = Arm.objects.filter(date=tm)
            client_rn = query_rn.prefetch_related('cmrs')
            args = {'query_rn': query_rn,
                    'cl_rn': client_rn,
                    'query_tm': query_tm,
                    'query_ys': query_ys,
                    'query_set': query_set
                    }
            return render(request, 'personnel/schedule/test-schedule-full.html', args)

And the template

<tbody id="add">
                {% for query in query_rn %}
                    <tr class="row100 body {{ query.status }}" data-href="/personnel/arm/{{ query.id }}">
                        <td class="cell100 column1">{{ query.driver }}</td>
                        <td class="cell100 column2">{% for idem in cl_rn.cmrs.all %} {{ idem.client }} {% endfor %}</td>
                        <td class="cell100 column3">{{ query.des_from}}</td>
                        <td class="cell100 columnarrow"><i class="fas fa-arrow-circle-right"></i></td>
                        <td class="cell100 column4">{{ query.des_to }}</td>
                    </tr>
                {% endfor %}
                </tbody>

What I am trying to do is to show all the values of the client field of an CMR objects that are linked with Arm in <td class="cell100 column2"></td> but it shows nothing instead.


Solution

  • It doesn't make sense to have separate querysets for the prefetch_related call. You're iterating through query_rn, you need to define the prefetch_related on that same queryset and then iterate through the related objects from there; you don't need client_rn at all. So:

    query_rn = Arm.objects.filter(date=rn).prefetch_related('cmrs')
    

    ...

    {% for query in query_rn %}
        {% for idem in query.cmrs.all %} {{ idem.client }} {% endfor %}
    {% endfor %}
    

    Note also, the first line of your code is a bit off. You shouldn't use __in with a single-list element, just check for equality; and since you just want to check that the related group exists, you should use the exists() method, which is slightly more efficient:

    if us.groups.filter(name='prime').exists():