Django - проблемы с выбором значений на основе отношения FK в views.py

У меня есть две модели, которые выглядят следующим образом;

class Body(models.Model):
    body_id = models.AutoField(primary_key=True)
    is_adult = models.BooleanField(default=False)
    body = models.TextField()
    add_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    add_date = models.DateTimeField()
    edit_user = models.CharField(max_length=25, blank=True, null=True)
    edit_date = models.DateTimeField(blank=True, null=True)
    category = models.ForeignKey(Category, models.CASCADE)

    class Meta:
        managed = True
        db_table = 'jdb_body'


class BodyTag(models.Model):
    body_tag_id = models.AutoField(primary_key=True)
    body = models.ForeignKey('Body', models.CASCADE)
    tag = models.ForeignKey('Tag', models.CASCADE, db_column='tag')

    class Meta:
        managed = True
        db_table = 'jdb_body_tag'

    def __str__(self):
        return self.tag

У меня есть представление, которое выглядит следующим образом;

def index(request):
latest_body_list = Body.objects.all().order_by('-body_id')
context = {
    'latest_body_list': latest_body_list
}
return render(request, 'index.html', context)

Это представление дает мне список Body записей без проблем. Я пытаюсь отобразить Body записей с соответствующими BodyTag записями. Что я делаю неправильно?

Вам нужно поле ManyToManyField в классе Body

tags = models.ManyToManyField('Tag')

Доступ

body = Body.objects.get(body_id=1)
tags = body.tags.all()

Если вы имеете в виду отображение этих данных в шаблоне, то все, что вам нужно сделать, это проследить отношения ForeignKey в обратном порядке. Это показано в документации для представлений, но в шаблоне это будет выглядеть примерно так же. Что-то вроде:

{% for body in latest_body_list %}
    {{ body }}
        {% for tag in body.tag_set.all %}
            {{ tag }}
        {% endfor %}
{% endfor %}

-set - это то, что говорит django смотреть назад в отношениях ForeignKey.

Возможно, лучшим способом, также показанным в документации, будет определение related_name в вашем ForeignKey:

class BodyTag(models.Model):
    body_tag_id = models.AutoField(primary_key=True)
    body = models.ForeignKey('Body', models.CASCADE, related_name='tags')
    tag = models.ForeignKey('Tag', models.CASCADE, db_column='tag')

Тогда ваш шаблон может быть написан немного лучше:

{% for body in latest_body_list %}
    {{ body }}
        {% for tag in body.tags.all %}
            {{ tag }}
        {% endfor %}
{% endfor %}
Вернуться на верх