Django ManyToManyField ссылается на себя: рендеринг в шаблон - PullRequest
0 голосов
/ 13 октября 2018

Ниже приведен код проекта, над которым я работаю.Как вы можете видеть в представлении, я выполняю запрос для объектов в модели риска, которые связаны с первичным ключом в URL.

Проблема в том, что я не могу получить доступ к атрибутам запрашиваемого объекта.

Модель

class Risk(models.Model):
    risk_title = models.CharField(max_length=60)
    root_causes = models.ManyToManyField('self',
                                         through='Roots',
                                         symmetrical=False,
                                         related_name='root_cause')


class Roots(models.Model):
    causal_risk = models.ForeignKey(Risk, related_name='causes', on_delete=models.CASCADE)
    effected_risk = models.ForeignKey(Risk, related_name='effected_risk', on_delete=models.CASCADE)

Просмотр:

def view_risk(request, id):

    try:
           risk = Risk.objects.get(pk=id)
    except Risk.DoesNotExist:
           raise Http404("Risk does not exist")

       roots = Roots.objects.filter(effected_risk=id)


    args = {
        'risk': risk,
        'roots': roots,
       }
return render(request, 'risks/risk_detail.html', args)

Шаблон:

{% for root in roots %}

{{ root }}

{% endfor %}

Запуск приведенного выше кода возвращает это:

Roots object (2) Roots object (3)

Этого следует ожидать,так как это записи, которые я сделал для модели через интерфейс администратора.

Однако, когда я запускаю:

{% for root in roots %}

{{ root.risk_title }}

{% endfor %}

Экран остается пустым.

TLDR Передача запроса из промежуточной таблицы в шаблон работает, но шаблон не может получить доступ к атрибутам объекта.Как я могу выполнить приведенный выше запрос и затем получить доступ к объектам в шаблоне?

ОБНОВЛЕНО Включена часть рендеринга для ответа JoJo.Эта проблема была решена в моем другом обновлении.

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Я забыл запросить прямые атрибуты модели.Я получил то, что мне нужно с этим шаблоном:

{% for root in roots %}

{{ root.causal_risk.risk_title }}

{% endfor %}
0 голосов
/ 13 октября 2018

Обратите внимание, что в функции представления отсутствует оператор return, поэтому на самом деле html-страница вообще не отображается.

Если предположить, что html-шаблон имеет имя 'my_template.html', отсутствующий return должен выглядеть примерно так:

def view_risk(request, id):
    # ...
    return render(request, 'my_template.html', args)

Далее, как упоминал @JonHrovat, шаблон должен вызывать

{{ root.causal_risk.risk_title }}

внутри цикла for.

Примечание по эффективности :

Если вы звоните root.causal_risk.risk_title в шаблоне с вашим текущим запросом на roots, это приводит к дополнительнымзапросы, по одному на каждую итерацию.Этого можно избежать с помощью оператора select-related при запросе корней в функции представления:

roots = Roots.objects.select_related('causal_risk__risk_title').filter(effected_risk=id)
...