@olexndr090

Как вывести поля связанной таблицы по ManyToMany Through в шаблоне html?

Вот модели:
class Products(models.Model):
    code = models.IntegerField(blank=True, null=True, help_text="Код товару для швидкого пошуку")
    product_name = models.CharField(max_length=200, help_text="Назва запчастини")
    group = models.ForeignKey(Groups,on_delete=models.CASCADE, blank=True, null=True, help_text="Група до якої  відноситься запчастина")

    def __str__(self):
        return self.product_name


class Connections(models.Model):
    service = models.ForeignKey(Services, on_delete=models.CASCADE, blank=True, null=True, help_text="Послуга до якої додати запчастини")
    product_item = models.ManyToManyField('Products', through='ThroughProducts')

    def __str__(self):
        return self.service.service_name

class ThroughProducts(models.Model):
    connection = models.ForeignKey(Connections, on_delete=models.CASCADE, related_name='connections')
    product = models.ForeignKey('Products', on_delete=models.CASCADE, related_name='product')
    value_product = models.IntegerField()

    def __str__(self):
        return self.connection.service.service_name

Они работают. В админке добавил несколько значений и все выводится, но я не могу в шаблоне обратиться к привязанным полям.
Пробую следующий вариант:
<ul>
{% for connection in connections %}
   <li class="connect-service">{{ connection.service.code }}</li>
    <ul>
        {% for n_product in connection.throughproducts_set.all %}
       <li class="connect-product select-item-product" data-index="{{ n_product.id }}">{{ n_product.value_product }}<input type="checkbox" class="option-add" value="1"></li>
        {% endfor %}
    </ul>
{% endfor %}
</ul>

Ничего не выводит. В любых комбинациях, даже если есть related_name.
Следующий вариант работает:
<ul>
{% for connection in connections %}
   <li class="connect-service">{{ connection.service.code }}</li>
    <ul>
        {% for n_product in connection.product_item.all %}
            {% for item in value %}
                {% if item.product == n_product and item.connection == connection %}
                    <li class="connect-product select-item-product" data-index="{{ n_product.id }}">{{ n_product.product_name }} - {{ item.value_product }}<input type="checkbox" class="option-add" value="1"></li>
                {% endif %}
            {% endfor %}
        {% endfor %}
    </ul>
{% endfor %}
</ul>

Но в нем слишком много циклов. С большим количеством данных это неэффективно.
Как я могу получить такой же результат, как в работающем варианте, но правильным кодом?
  • Вопрос задан
  • 328 просмотров
Решения вопроса 1
@olexndr090 Автор вопроса
Решение нашел следующее, в модели создал функцию, для фильтрации и ее можно вызвать в шаблоне.
class Products(models.Model):
    code = models.IntegerField(blank=True, null=True, help_text="Код товару для швидкого пошуку")
    product_name = models.CharField(max_length=200, help_text="Назва запчастини")
    group = models.ForeignKey(Groups,on_delete=models.CASCADE, blank=True, null=True, help_text="Група до якої  відноситься запчастина")

    def __str__(self):
        return self.product_name

    def get_products(self):
        return ThroughProducts.objects.filter(product=self.id)

В шаблоне вот так вызывается:
{% for n_product in product.get_products %}
       <li>{{ n_product.value_product }}</li>
        {% endfor %}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@RipperZX
Думаю что стоит подумать о том что логику вынести во view., не стоит такое шаблонизатором делать!
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы