фото Израиль Паласио на Бессмысленно
Таким образом, у вас есть модель с внешним ключом:
from django.db import models from .models import Author class Book(models.Model): name = models.CharField(...) author = models.ForeignKey(to=Author,...)
Теперь вы хотите увидеть Автор
На вашей панели администратора. Легко, верно? Просто добавь:
def __str__(self): return f'{self.id} {self.author.name}'
Что это сделает, это ударить нашу базу данных для имени автора для каждой строки, присутствующей на странице. Представьте себе, что есть 100 рядов. Это 100 больше хитов. Эта проблема известна как N + 1 запрос
Отказ
Решение довольно простое. Если это Иностранник
, вам нужно использовать select_related
на вашем запрос
. Если это Manytomany
поле или обратное FK
тогда вам нужен Prefetch_related
метод. И, кстати, это разница между этими двумя методами. Это обычный вопрос интервью.
Но в нашем случае это не простой запрос. Если вы действительно хотите исправить, что вам нужно будет глубже в том, как Django Admin работает и предоставляет пользовательские Queryset
к мнению.
Когда я столкнулся с этой проблемой, решение, которое было принято, просто удалил ссылку на Викторина
от __str__
Метод ¯ \ _ (ツ) _/¯ ¯
Немного Todo для себя: найдите способ решить это через select_related.
Некоторое время я не столкнулся с этой проблемой, но не так давно я сделал. Итак, как я уже сказал, решение этого довольно просто. Все, что нам нужно сделать, это переопределить get_queryset
Метод на модели администратора. Например:
@admin.register(models.Book) class BookAdmin(admin.ModelAdmin): def get_queryset(self, request): qs = self.model._default_manager.select_related( 'author', ) # This stuff is marked as TODO in Django 3.1 # so it might change in the future ordering = self.get_ordering(request) if ordering: qs = qs.order_by(*ordering) return qs
Теперь будет только один запрос за запись, содержащую Присоединяйтесь к
пункт, ударяя нашу базу данных.
Оптимизация ftw 😏.
Оригинал: “https://dev.to/c_v_ya/why-foreignkey-reference-in-django-model-s-str-method-is-a-bad-idea-41a7”