Как вывести значение поля, а не объект?

  • Проект на Django
  • Используется внешняя таблица от другого проекта (PostgreSQL) в Read-Only
  • В таблицах, в качестве PrimaryKey используется текстовая строка "UUID" (вида: "abcdef-text-1r4trctstfytfuk2r"). Не спрашивайте, почему...

Окей, сделал модели, создал представление для вывода сообщений таблицей. Нужно чтобы в таблице отображалось имя автора в виде ссылки на страницу с персональной инфой о авторе.

Всё работает, но есть проблема и вопрос:

  1. Django вместо ожидаемого Join'а (в sql) делает отдельные запросы в базу для каждого message (сотни SQL Запросов на страницу!). Почему так получилось и как это "вылечить"?
  2. Как получить "Сырое" значение поля? {{ message.author }} - ожидаемо, вернет "Object что-то-там". А как получить саму строку, что хранится в соответствующей колонке таблицы?

Код примерно такой:

class Author(models.Model):
    uuid = models.CharField(primary_key=True, max_length=32)
    name = models.CharField(max_length=128, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'external_author'


class Message(models.Model):
    uuid = models.CharField(primary_key=True)
    author = models.ForeignKey(Author, models.DO_NOTHING)
    text = models.CharField(max_length=4000, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'external_message'


class Messages(ListView):
    model = Message
    paginate_by = 25
{% for message in object_list %}
<a href="{{ url 'author_details' pk=message.author.uuid }}">{{ message.author.name }}</a>
{% endfor %}

Ответы (1 шт):

Автор решения: Fox_exe

В общем, всё просто - достаточно дописать к интересующему полю "_id":

{% for message in object_list %}
<a href="{{ url 'author_details' pk=message.author_id }}">{{ message.author.name }}</a>
{% endfor %}

--> {{ message.author_id }}

Остлось под вопросом, почему Django делает prefetch_related вместо select_related, когда обращаешся к полям с зависимостями. Конечно, можно это обойти, явно указав select_related() в View -> queryset (или переопределив get_queryset())... Но это костыль...

→ Ссылка